* [[PHP PG]] PHPのプログラムのTIPSです。 #contents ** TIPS ***コーディング規約 [[付録 B. Zend Framework PHP 標準コーディング規約>http://framework.zend.com/manual/ja/coding-standard.html]] ***ダブルクォーテーションとシングルクォーテーションの違い ダブルクォーテーション 括弧内の変数は認識される。~ シングルクォーテーション 括弧内の変数は認識しない。~ ***requireとincludeの違い requireはスクリプト解析前に置き換えされ、includeはそのときに置き換えられます。このためループでまわして、都度読み込みたいような場合は、includeを使います。require_onceとinclude_onceは1度しか評価を行わないので、2回以上読み込まれて、再定義エラーになる場合に使用します。 ***ログをとる error_log("ログ",3,"/webroot/error.log"); を埋め込みます。 0:php.iniのerror_log参照 1:メール 2:他ホスト通知 3:ログファイル ***apacheにログをとる apache_noteを使う。~ [[apacheのログに好きな情報を出す方法(PHP編)>http://neta.ywcafe.net/000607.html]] *** 配列 -配列の中身の表示 for( $i=0; $i<count($hoge); $i++ ) { echo "<p>".$hoge[$i]; } -連想配列の場合 reset($hoge); //foreachが最初に戻してくれるので、わざわざ最初に戻す必要もない foreach($hoge as $key => $val) { echo "<p>".$key.":".$val; } -初期化 $hogearray = array(); *** ブラウザで中止しても続行させたい php.iniに ignore_user_abort = On またmax_execution_timeを大きくしておきましょう ***mbstring http://php.s3.to/man/ref.mbstring.html ***変数のデータ型 gettype($hoge); もしくはis_array()とかで参照する。 ***substr 他の言語をさわっているとよく間違える... [[String 関数 - 文字列の一部分を返す>http://www.phppro.jp/phpmanual/php/function.substr.html]] ***文字列のバイト数 strlen(bin2hex($hoge))/2 mb_strwidthはなんかおかしいんだよな... ***fgetcsvで文字化け 使えそうで使えなかった... ので大変よくないやり方ですが、 //while ($data = fgetcsv($fp,2048)) { while ($data1 = fgets($fp,2048)) { $data1 = mb_convert_encoding($data1,"EUC-JP","SJIS"); $data = mb_split(",",str_replace('"','',$data1)); なんだこりゃ... ~ ということで、こちらを参照しましょう。 [[CSVの読み込み>http://project-p.jp/halt/kinowiki/php/Tips/csv]]~ [[fgetcsv で文字化け、fgetcsv_reg を試す。>http://sfi.hamazo.tv/e1137876.html]]~ [[fgetcsv関数を使用した場合の文字化けについて>http://saboten009.blogspot.com/2007/05/fgetcsv.html]]~ [[PHP5でfgetcsvが正常に動作しない>http://yossy.iimp.jp/wp/?p=56]]~ ***チェックボックス http://www.fukushi-net.or.jp/takamoto/php/checkbox/ ***=&とは $hoge1 =& $hoge2とかで使ってたりしますが、これはリファレンスです。ポインタみたいなもんでしょうか。 ***日付 日付をフォーマットしたい場合に、 date("Y-m-d", strtotime("2007/02/10 22:40:00")); [[日付フォーマット>http://php.benscom.com/manual/ja/function.date.php]] ***1年前 date("Y-m-d",mktime(0,0,0,date("m"),date("d"),date("Y")-1)); 1日前とか1ヶ月前も同じ要領で。こんなことしなくても、 date('Y-m-d', strtotime('-1 day')); とか +3 weekで3週間後、-5 daysで5日前、-1 month で一ヶ月前。 ***strposの戻り値がintとboolean? 見つかった場合は見つかった文字の開始位置、見つからなかった場合は、falseって型が違うではないか。この場合は、!==という比較演算子をつかいましょう。===もあります。 ***==の比較がおかしい? $a = "00001"; $b = "01"; if ($a == $b) { //ここを通る } なんってこった....... ===かstrcmpを使います。 ***HTTP_Request これはHPの自動取得や自動POSTなどいろいろと応用がきくのでぜひ使いましょう。JAVAの場合は、HttpClientを使えば楽にできます。Etherealを使って調べながらやりましょう。 $req =& new HTTP_Request("http://www.hoge.ho"); GET,POSTしたいURLを指定します。必要ならばヘッダを付加します。 $req->addHeader("User_Agent","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)"); POSTの場合、変数と値をセットします。 $req->addPostData('koumoku','atai'); セットが終わったらリクエストを投げます。 $response = $req->sendRequest(); エラーかどうかを調べます。 if (PEAR::isError($response)) { // エラー表示 echo "エラー:".$req->getResponseCode(); もしくは $code = $req->getResponseCode(); で、そのレスポンスコードを確認します。404はNot Foundとかです。302とかであれば、LocationにリダイレクトされるURLがありますので、 $nexturl = $req->getResponseHeader("Location"); で取得して、 $req->setURL($nexturl); でURLをセットしておいて、もう一度 $response = $req->sendRequest(); とします。setURLでセットしたURLは $req->_url->url で参照可能です。エラーでないなら、 $body = $req->getResponseBody(); で取得したhtmlを$bodyに入れます。これを好きな形に加工します。 もし取得したデータを一行一行処理したいなら、 $bodyline = mb_split("\n",$body); foreach($bodyline as $linedata){ でグルグルまわします。他にもいろいろとありますので、ほんの一例です。cookieが必要なら、(ログインがあるような場合) $cookies = $req->getResponseCookies(); で取得しておきます。このcookieを渡したい場合は、 foreach ($loginCookies as $cookie) { $req->addCookie($cookie['name'], $cookie['value']); } でセットします。 ***URL分解 parse_urlを使います。 $urlary = parse_url("http://hidekazu.dhs1.sst.ne.jp/pukiwiki/pukiwiki.php"); で、 $urlary['scheme']; http $urlary['host']; hidekazu.dhs1.sst.ne.jp $urlary['path']; /pukiwiki/pukiwiki.php 他にport,user,pass,query,fragmentとかあります。 ***正しいDNSかどうかをチェックしたい。 //@以降を$hostpartに入れる if (!checkdnsrr($hostpart,"ANY")) { //error } http://www.teu.ac.jp/chiit/~dsuzuki/phpdoc/function.checkdnsrr.html *** HTTPの環境変数取得 [[Perl・PHP・JavaでHTTP環境変数を取得する方法>http://iwamode.net/etc/cgi_env_param.html]] ***非同期実行 system("/home/your/bgprog $arg1 $arg2 > /dev/null &"); 動かない場合は、> test.logとかしてログを出すかパスが通っているか調べるために set > path.log とかして、確認しておこう。 ***待ち sleep(秒); usleep(マイクロ秒); ***タイムアウト set_time_limit(秒数) セーフモードで実行されていると無効になるので、もしくはphp.iniでmax_execution_time で指定しておけば長いスクリプトに対応できます。セッションが維持される長さについては、session.gc_maxlifetimeの値を変更します。 ***戻るボタン PHPで戻るボタンを押すとキャッシュの有効期限れといわれる場合は、 $utime = date( "U" ) + 60 * 60 * 24; $expires = date( "D, d M Y H:i:s", $utime )." GMT"; header("Expires: {$expires}"); header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); とすればいいらしいのですが、XOOPSでいまいちうまくいきません。includeのfunction.phpやcp_function.phpあたりに header ('Content-Type:text/html; charset='._CHARSET); header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); header('Cache-Control: no-store, no-cache, max-age=1, s-maxage=1, must-revalidate, post-check=0, pre-check=0'); header("Pragma: no-cache"); の記述があり、このあたりだとは思うのですが... とりあえずfirefoxで LiveHTTPHeadersをいれて覗いていると、うまくいっているほうは、 Cache-Control: private, no-cache だめなほうは、 Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 となっている。 [[PHP/「ページの有効期限切れ」対策>http://www.glamenv-septzen.net/pukiwiki/index.php?PHP%2F%A1%D6%A5%DA%A1%BC%A5%B8%A4%CE%CD%AD%B8%FA%B4%FC%B8%C2%C0%DA%A4%EC%A1%D7%C2%D0%BA%F6]] ***ダウンロード $len = filesize($file_name); header("Content-type: application/force-download"); header("Content-Disposition: attachment ; filename=download.csv"); header("Content-Length: ". $len) ; //ファイル出力(文字コード変換含む) $kanji_code=mb_internal_encoding(); // 現在の内部文字コードをキープ mb_http_output("SJIS"); // HTTP文字コードをSJISに明示的に設定 readfile($file_name); // ファイルを読み込んでHTTP出力 mb_internal_encoding($kanji_code); // 内部文字コードを元に戻す //テンポラリファイルを削除 unlink($file_name); ***ディレクトリの中のファイルを削除 $dellpath = "/work"; $dir = opendir($dellpath); while($file = readdir($dir)) { if(is_file($dellpath."/$file")) { unlink($dellpath."/$file"); } } closedir($dir); ***文字の長さ マルチバイトの時に全角2バイト、半角1バイトとして計算したい場合。 mb_strwidth($test) <--長さ mb_strimwidth($test,0,40,''); <--40バイトで切る ***ファイルシステムに関する関数の戻り値がおかしい キャッシュがきいているかもしれないので、clearstatcache()でクリアしておいきましょう。 ***配列の中身を確認したい。 print_r($ary); ***タグを消したい! strip_tags ***スパム対策の画像を作りたい。 アンチスパム画像だと思っていたんですが、CAPTCHA(completely automated public Turing test to tell computers and humans apart)っていうんですね。知らなかったです。~ KCAPTCHAが一番見やすい画像でした。JpGraphも簡単でよかったんですが、画像が見づらかったです。 参考:~ [[ランダムに生成される画像を利用してフォームの検証を行う>http://www.phppro.jp/news/116]]~ [[アンチスパム・イメージを使った認証>http://www.pahoo.org/e-soul/webtech/phpgd/phpgd-07-01.shtm]]~ [[PHPで使えるCAPTCHA画像作成ライブラリまとめ:phpspot開発日誌>http://phpspot.org/blog/archives/2006/11/phpcaptcha.html]]~ [[KCAPTCHA>http://goodphp.mirrors.phpclasses.org/browse/package/3193.html]]~ ***スパムがうざい [[スパム防止に使えるPEARパッケージ「PEAR::Net_DNSBL」>http://phpspot.org/blog/archives/2008/10/pearpearnet_dns.html]] ***PDF PHPからPDFを生成したい場合、TCPDFというものがあります。ただし日本語化けるそうなのですが、どうなんでしょうか。~ php4でやってみます。 wget http://downloads.sourceforge.net/tcpdf/tcpdf_4_0_027_php4.zip?modtime=1221827720&big_mirror=0 unzip tcpdf_4_0_027_php4.zip mv tcpdf_php4 /usr/local/lib/php /usr/local/lib/phpはphp.iniのincludeのところ cd /usr/local/lib/php/tcpdf_php4/fonts/utils/src/ttf2ufm-src make all ん?エラーが... scripts/unhtml <FONTS.hpux.html >FONTS.hpux /bin/sh: scripts/unhtml: 許可がありません とりあえず、 chmod -R 777 /usr/local/lib/php/tcpdf_php4/fonts/utils/src/ttf2ufm-src make all make install これでttf2pt1がつかえる。 wget http://ossipedia.ipa.go.jp/ipafont/IPAfont00203.php unzip IPAfont00203.zip cd IPAfont00203 ttf2pt1 -a -F ipag.ttf /usr/local/lib/php/tcpdf_php4/fonts/utils/makefont.php ipag.ttf ipag.ufm cp ipag.php /usr/local/lib/php/tcpdf_php4/fonts/ipagothic.php cp ipag.ctg.z /usr/local/lib/php/tcpdf_php4/fonts/ cp ipag.z /usr/local/lib/php/tcpdf_php4/fonts/ なんか重いな... 参考:~ [[TCPDF>http://www.tecnick.com/public/code/cp_dpage.php?aiocp_dp=tcpdf]]~ [[TCPDFで日本語を使うサンプル>http://hrgs.xrea.jp/2006/08/24/how_to_use_japanese_with_tcpdf]]~ [[TCPDF 日本語化について>http://www.bluemooninc.biz/~xoops/modules/pukiwiki/?tcpdf]]~ [[PHPでPDF生成>http://d.hatena.ne.jp/yukiwata/20080205/1202195198]]~ [[【PDF処理 -- PHP】 FPDF v1.6 + FPDI 日本語利用詳細>http://winofsql.jp/VA003334/phpVarious080825125024.htm]]~ [[PHP + TCPDF + FPDI + FPDI_Template>http://makisuke.seesaa.net/article/106821444.html]]~ オーバーレイぽく使えるかも。 では[[FPDF>http://www.fpdf.org/]]を見てみましょう http://www.fpdf.org/en/dl.php?id=99にドキュメントがあります。 fpdf16.zipをダウンロードしました。 unzip fpdf16.zip mkdir /usr/local/lib/php/pdf cp fpdf.php /usr/local/lib/php/pdf/ cp -rf font /usr/local/lib/php/pdf/ wget http://www.fpdf.org/download/japanese.zip unzip japanese.zip cp japanese.php /usr/local/lib/php/pdf japanese.phpを修正します。 function AddSJISFont($family='SJIS')の $name='KozMinPro-Regular-Acro'; を $name='MSGothic'; では、動かしてみましょう。 <?php require('pdf/japanese.php'); define(SC_CHAR, "EUC-JP"); $pdf = new PDF_Japanese(); $pdf->AddSJISFont(); $pdf->Open(); $pdf->AddPage(); $pdf->SetFont('SJIS', '', 9); $pdf->Text(0, 10, sjis_conv("テスト")); $pdf->Output(); function sjis_conv($conv_str) { return (mb_convert_encoding($conv_str, "SJIS", SC_CHAR)); } ?> あら? FPDF error: mbstring overloading must be disabled php.iniを見ると、 mbstring.func_overload = 7 になっている。0にすれば出力されました。.htaccessに php_value mbstring.func_overload 0 とでもしておくか。 ん?windowsではゴシックでmacでは明朝になった... 次は、FPDIです。既存のPDFをテンプレートとして、そのPDFに文字を埋め込めます。 ではhttp://www.setasign.de/products/pdf-php-solutions/fpdi/のDownloadより FPDI-1.2.1.zip FPDF_TPL-1.1.2.zip 両方解凍後、 cp -rf * /usr/local/lib/php/pdf/ 次にjapanese.phpを修正します。 require('fpdf.php'); の下に require('fpdi.php'); を追加 class PDF_Japanese extends FPDF を//でコメントして、 class PDF_Japanese extends FPDI を追加。 ではテンプレートのファイルをtmp.pdfとして、そのPGのある場所に置いて、動かしてみましょう。 <?php require('pdf/japanese.php'); define(SC_CHAR, "EUC-JP"); define(TMPL_PDF, "tmp.pdf"); $pdf = new PDF_Japanese(); $pdf->AddSJISFont(); $pdf->Open(); $pageno = $pdf->setSourceFile(TMPL_PDF); $tplidx = $pdf->ImportPage(1); $pdf->AddPage(); $pdf->SetFont('SJIS', '', 9); $pdf->useTemplate($tplidx); $pdf->Text(0, 10, sjis_conv("テスト1")); $pdf->SetFont('SJIS', '', 30); $pdf->Text(30, 100, sjis_conv("テスト2")); $pdf->SetFont('SJIS', '', 20); $pdf->Text(50, 50, sjis_conv("テスト3")); $pdf->Output(); function sjis_conv($conv_str) { return (mb_convert_encoding($conv_str, "SJIS", SC_CHAR)); } ?> では今度はjapanese.zipではなく、[[mbfpdf10b.zip>http://www.geocities.jp/rui_hirokawa/php/pdf/mbfpdf10b.zip]]を使ってみましょう。 解凍後、 cp -rf * /usr/local/lib/php/pdf/ で、 <?php require_once 'pdf/mbfpdf.php'; $GLOBALS['EUC2SJIS'] = true; $pdf=new MBFPDF('P', 'mm', 'A4'); $pdf->AddMBFont(GOTHIC ,'SJIS'); $pdf->AddPage(); $pdf->SetFont(GOTHIC,'',20); $pdf->Write(10,"サンプル文字列"); $pdf->Output(); ?> ではこちらもFPDIに対応させましょう。MBfpdi.phpを開いて require('fpdf.php'); の下に require('fpdi.php'); を追加、また class MBFPDF extends FPDF を class MBFPDF extends fpdi に変更します。 <?php require_once 'pdf/mbfpdf.php'; $GLOBALS['EUC2SJIS'] = true; define("SC_CHAR", "EUC-JP"); define("TMPL_PDF", "tmp.pdf"); $pdf=new MBFPDF('P', 'mm', 'A4'); $pdf->AddMBFont(GOTHIC ,'SJIS'); $pdf->Open(); $pageno = $pdf->setSourceFile(TMPL_PDF); $tplidx = $pdf->ImportPage(1); $pdf->AddPage(); $pdf->SetFont(GOTHIC, '', 9); $pdf->useTemplate($tplidx); $pdf->Text(0, 10, sjis_conv("テスト1")); $pdf->SetFont(GOTHIC, '', 30); $pdf->Text(30, 100, sjis_conv("テスト2")); $pdf->SetFont(GOTHIC, '', 20); $pdf->Text(50, 50, sjis_conv("テスト3")); $pdf->Output(); function sjis_conv($conv_str) { return (mb_convert_encoding($conv_str, "SJIS", SC_CHAR)); } ?> 参考:~ [[FPDFを使ったPDF作成>http://www.phpbook.jp/fpdf/]]~ [[PHP:PDF帳票(FPDF+FPDI+文字回転)>http://shikabo.ddo.jp/?cat=72]]~ [[PDF関連情報>http://www.geocities.jp/rui_hirokawa/php/pdf/]] ***QR http://blog.webcreativepark.net/2007/09/17-194842.html ***MySQLへの複数接続 $dbsaki = mysql_connect("host","user","pass"); //これがいる mysql_select_db("dbname", $dbsaki); //クエリ $sql = "select ...."; mysql_query($sql,$dbsaki); 参考:http://oshiete1.goo.ne.jp/kotaeru.php3?q=1447277 ***MySQLのAUTO_INCREMENTで生成された値を取得したい。 mysql_insert_id() ***カンマ編集、ゼロサプレス(ゼロパディング) number_format sprintf("%03d", $hoge); ***邪魔な文字を消したい。 たとえば数値アルファベット以外を消したい場合は、 $hoge = ereg_replace("[^a-zA-Z0-9]", "", $hoge); ***文中のURLをリンクへ,メールアドレスをmaillto $kkbody = ereg_replace("[[:alpha:]]+://[^<>[:space:]]+[[:alnum:]/]","<a href='\\0' target='_blank'>\\0</a>",$kkbody); $match = '[0-9,A-Z,a-z][0-9,a-z,A-Z,_,\.,-]+' .'@[0-9,A-Z,a-z][0-9,a-z,A-Z,_,\.,-]+\.' .'(com|net|org|gov|edu|int|mil|biz|info|name|pro|jp|af|al|dz|as|ad|ao|ai|aq|ag|ar|am|aw|ac|au|at|az|bh|bd|bb|by|bj|bm|bt|bo|ba|bw|br|io|bn|bg|bf|bi|kh|cm|ca|cv|cf|td|gg|je|cl|cn|cx|cc|co|km|cg|cd|ck|cr|ci|hr|cu|cy|cz|dk|dj|dm|do|tp|ec|eg|sv|gq|er|ee|et|fk|fo|fj|fi|fr|gf|pf|tf|fx|ga|gm|ge|de|gh|gi|gd|gp|gu|gt|gn|gw|gy|ht|hm|hn|hk|hu|is|in|id|ir|iq|ie|im|il|it|jm|jo|kz|ke|ki|kp|kr|kw|kg|la|lv|lb|ls|lr|ly|li|lt|lu|mo|mk|mg|mw|my|mv|ml|mt|mh|mq|mr|mu|yt|mx|fm|md|mc|mn|ms|ma|mz|mm|na|nr|np|nl|an|nc|nz|ni|ne|ng|nu|nf|mp|no|om|pk|pw|pa|pg|py|pe|ph|pn|pl|pt|pr|qa|re|ro|ru|rw|kn|lc|vc|ws|sm|st|sa|sn|sc|sl|sg|sk|si|sb|so|za|gs|es|lk|sh|pm|sd|sr|sj|sz|se|ch|sy|tw|tj|tz|th|bs|ky|tg|tk|to|tt|tn|tr|tm|tc|tv|ug|ua|ae|uk|us|um|uy|uz|vu|va|ve|vn|vg|vi|wf|eh|ye|yu|zm|zw)'; $kkbody = ereg_replace($match,"<a href='mailto:\\0'>\\0</a>",$kkbody); ***文字列折り返し マルチバイトの2バイト目とか考えるの面倒なときは、mb_strcutを使ってやれば。 ***デーモンを作る [[【PHP TIPS】 57. PEAR::Net_Serverでサーバデーモンを作ろう>http://itpro.nikkeibp.co.jp/article/COLUMN/20070910/281513/]]~ [[1.7 プログラムをデーモンとして動かすにはどうすればいいですか?>http://www.adl.nii.ac.jp/~moro/unix-programmer/faq-j_2.html#SEC16]]~ ***GDを使って画像加工したい [[PHP GDプログラミング>http://www.geekpage.jp/web/php-gd/]] ***画像保存 <?php $temp=file_get_contents("http://www.google.co.jp/intl/ja_jp/images/logo.gif"); $handle=fopen("test.gif","w"); fwrite($handle,$temp); fclose($handle); ?> ***画像合成 <?php // 1枚目 $im1 = ImageCreateFromJpeg("a.jpg"); // 合成したいファイル $im2 = ImageCreateFromGif("b.gif"); // 合成 ImageCopy($im1, $im2, 470, 400, 0, 0, 169, 85); // 保存 書き込めないときは権限を見直しましょう Imagejpeg($im1,"/hoge/c.jpg"); // 破棄 ImageDestory($im1); ImageDestory($im2); ?> ***出力バッファ ob_flushとflushの違いを理解しよう。 [[出力バッファ制御>http://www.y2sunlight.com/water/webman/php1/1X.4.html]]~ ** リンク ***[[Windows機種依存文字の解消>http://www.kauda.jp/~suguru/comp/php/scriptlets/mdcs/]] 機種依存文字の解消のサンプルを提供していただいております。 ***[[レッツPHP! Webメーラ>http://php.s3.to/net/#mail]] Webメーラーのサンプルがあります。 ***[[PHP 基礎編9 - 正規表現、マッチ、置き換え、ereg、eregi、eregi_replace>http://homepage2.nifty.com/sak/w_sak3/doc/sysbrd/php_k09.htm]] ***[[セキュアな PHP アプリケーションを作成するための 7 つの習慣>http://www.ibm.com/developerworks/jp/opensource/library/os-php-secure-apps/]] ***[[PHP でオブジェクト指向の設計をするための 7 つの良い習慣を身につける>http://www.ibm.com/developerworks/jp/opensource/library/os-php-7oohabits/?ca=drs-jp]] ** 参考書籍 ** コメント --#comment