* [[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

トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS