2018年12月13日

【PHP】単体では使わないけど何かと便利な記述。

PHPで記述する細かいもの系。
	mt_srand((int)(((float)microtime()) * 1000000));

mt_randをさらに制度の高い乱数にするための記述。
特定条件下の場合mt_randが常に同じ結果を繰り返すので、そこにアクセス時のマイクロ秒を与えることによって常に違う乱数を発生させるために必要だったりする。
※PHP7.1で修正されているらしい?

	//同じページに何度も読み込ませられるrequire
require(dirname( __FILE__ ).'/index.html');
//同じページに1回だけ読み込ませられるrequire_once
require_once(dirname( __FILE__ ).'/index.html');

よく使っているのはrequire_onceで、設定ファイルを読み込ませるのによく使う。
エラーが出たときに止めないincludeの方が運用ではいいのかもしれないけど、明らかにおかしい状態じゃないとエラーに気づかないので、require使ってる。

	function moji_code($str){
foreach(array('UTF-8','EUC-JP','ASCII','SJIS','JIS') as $charcode){
if(mb_convert_encoding($str, $charcode, $charcode) == $str){
return $charcode;
}
}
return null;
}
if(moji_code($_POST["memo_box"]) != 'SJIS'){
$_POST["memo_box"] = mb_convert_encoding($_POST["memo_box"], "SJIS", "UTF-8,EUC-JP,ASCII,JIS");
}

文字コードを判定するfunctionと、SJISじゃなかったらSJISに変換するif文。
今見たらこれfunctionに第二引数入れて変換も一緒にできるんじゃないかと気づいた。

	function moji_code($str, $code){
foreach(array('UTF-8','EUC-JP','ASCII','SJIS','JIS') as $charcode){
if(mb_convert_encoding($str, $charcode, $charcode) == $str){
$str = mb_convert_encoding($str, $code, $charcode);
return $str;
}
}
return null;
}
$word = "文字コード変換";
$moji = moji_code($word,"SJIS");

これで普通に変換したい文字列と文字コードで変換出来た。
やっぱ数年経って見返すと無駄な部分とか見えてくるなぁ。
でも汎用性で言うなら文字コードだけ返すのも問題なく使えるとは思うけど。
posted by Lc at 23:40 | Comment(0) | PHP | このブログの読者になる | 更新情報をチェックする

2018年12月11日

【PHP】curlを使ったfile_get_contents。

file_get_contentsが若干遅いからcurlを使って高速化してfunction化。
	function file_cget_contents($address){
$ch = curl_init(); //初期化
curl_setopt($ch, CURLOPT_URL, $address); //URLの設定
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); //出力内容を受け取る設定
$result = curl_exec($ch); //データの取得
curl_close($ch); //cURLのクローズ

return $result; //データを返す
}
//使い方
$data = file_cget_contents('http://lcsious.com/');

どこかで拾ってきたはずcurlのfunctionなんだけど、元のページが見つからなかった。
このcgetはまんまfile_get_contentsの代わりとして使えて、半分の時間くらいで取得できる。
なおかつオプションをいろいろ設定できてfile_get_contentsよりも軽量化できる。
よく使う軽量化オプションはこちら。
		curl_setopt($ch, CURLOPT_HEADER, TRUE);
curl_setopt($ch, CURLOPT_NOBODY, TRUE);
curl_setopt($ch, CURLOPT_USERAGENT, $user_agent);
curl_setopt($ch, CURLOPT_REFERER, $ref_select);
curl_setopt($ch, CURLOPT_TIMEOUT, 2);

CURLOPT_HEADERを使うとステータスコードが取得できるので、エラーが出た場合404なのか503なのか他の要因なのかを調べることができる。
CURLOPT_NOBODYはCURLOPT_HEADERを使った場合にソースコード自体は要らないことが多いので、そういう場合に使える。ただし〜 の間を取得しないんじゃなく、ステータスコード以外の全てを取得しない。CURLOPT_NOBODYを指定しただけでヘッダーのみ出力するらしい。
CURLOPT_USERAGENT、まんまuseragentを指定できる。今では少ないが、携帯(ガラケー)のみで見れるコンテンツとかの取得に使えた。今ではスマホのみしか見れないとかがあまりに少ないので、使い所はあんまり無いかも。
CURLOPT_REFERER、リファラーを偽装できる。取得するサイトのトップページからしか応答を受け付けないようなサイトで使える。
CURLOPT_TIMEOUT、応答時間が長すぎたらその時点でアクセスを切り上げる時間設定(秒)。多くのURLを取得するならタイムアウトを短めに取らないと長くなって時間が結構かかる。

大量のURLをリスト化して動かすようにした状態が以下。
基本はここの記述→PHPで複数のURLを404チェックする関数の速度比較 | ウダ2Blog
	$urls = null;
//省略するけど$urlsにurlを詰め込むforeachとか組む
if($urls != null){ //$urlsがnullじゃなかったら開始
$num_hoji = $saisyo_num;
//ここからcurl_multi
$mh = curl_multi_init();
$ch_list = array();
foreach($urls as $mykey => $url) {
$ch_list[$mykey] = curl_init($url);
curl_setopt($ch_list[$mykey], CURLOPT_HEADER, TRUE);
curl_setopt($ch_list[$mykey], CURLOPT_NOBODY, TRUE);
curl_setopt($ch_list[$mykey], CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch_list[$mykey], CURLOPT_USERAGENT, $user_agent);
curl_setopt($ch_list[$mykey], CURLOPT_REFERER, $ref_select);
curl_setopt($ch_list[$mykey], CURLOPT_TIMEOUT, 5);
curl_multi_add_handle($mh, $ch_list[$mykey]);
}
$running = null;
do { curl_multi_exec($mh, $running); } while ( $running );
foreach($urls as $mykey => $url) {
$httpCode = curl_getinfo($ch_list[$mykey], CURLINFO_HTTP_CODE);
if (preg_match('/5[\d]{2}/',$httpCode)){
$url_echo[$mykey][] = $httpCode;
$url_echo[$mykey][] = 'サーバー負荷により停止しました。';
if (preg_match('/503/',$httpCode)){
break;
}
}
else if (preg_match('/200/',$httpCode)){
$url_echo[$mykey][] = $num_hoji;
$url_echo[$mykey][] = $urls[$mykey];
}
else if (preg_match('/404/',$httpCode)){
$url_notfound[$mykey][] = $num_hoji;
$url_notfound[$mykey][] = $urls[$mykey];
}
else {
$url_notfound[$mykey][] = $num_hoji;
$url_notfound[$mykey][] = $httpCode;
}
$num_hoji++;
curl_multi_remove_handle($mh, $ch_list[$mykey]);
curl_close($ch_list[$mykey]);
}
curl_multi_close($mh);
//ここまでcurl_multi
}

これはソシャゲの画像をひたすら確認するために作ったもので、連番.pngを2000枚くらい存在するかの調査のためのものでした。そのソシャゲが終わったので現状は使ってません。
これの良いところは毎回画像を取得するのではなく、ステータスコードだけを取得するのでサーバー側に不必要に負荷をかけないという点です。一時期モバマスが連番取得出来たので、サーバーに負荷がかかりすぎて連番画像をやめてちょっと複雑化した経緯があるので、そういう負荷対策をされにくいのと、そもそも負荷をほとんどかけないようにする点で非常に有用です。
最近はunity製ゲーム増えすぎて高画質pngをサーバーに直置きなんてことがほとんど無くなったので使える場面はなかなか少なくなりました。
タグ:Curl
posted by Lc at 21:17 | Comment(0) | PHP | このブログの読者になる | 更新情報をチェックする

2018年12月08日

【PHP】自分で作ったphpの覚え書きを適当に書いていくブログ。

ブログでphp書いてたらアフィでお小遣い稼ぎ出来ないかなって思ったから始めて見る。
大抵は検索した結果を湾曲しながら理解していつの間にか出来上がったようなページばっかりなので、何をどう書けばいいのかよくわからない。
基礎を知らないままやりたいことだけやってったらこうなったって例になればいいかな。
	//レンタル鯖を転々としてた時には絶対必要だった記述、運営によって時間軸がバラバラだからtimezoneをトーキョーに
date_default_timezone_set('Asia/Tokyo');
posted by Lc at 23:42 | Comment(0) | PHP | このブログの読者になる | 更新情報をチェックする