Home > PHP Archive

PHP Archive

Google Map APIを使って住所から緯度/経度を取得する

  • Posted by: zaru
  • 2008年2月 1日 19:04
  • PHP

Google Mapでマイマップを作って公開できるようになったり、またまたGoogle Mapが人気になってきたので少し使ってみました。今回は、住所リストはあるけど緯度/経度が分からない…。という時のためのメモ。

今回は、PHP5のSimpleXML関数を使ってGoogle Map APIから返されるXMLをパースして処理してみます。

Continue reading

PHPで配列の中に値があるか調べる関数 array_search() in_array() array_keys() 比較

  • Posted by: zaru
  • 2008年1月10日 15:30
  • PHP

PHPで配列の中に目的の値が入っているかどうかをチェックしたくなったので、良い感じの関数ないかなーとマニュアルを見ていたらいっぱい出てきました(PHPの場合、たいがい目的にあった関数が用意されていたりするので、組む前にチェックすると吉)。

それぞれ同じ目的を達成できますが、微妙に違うのでどれを使えば良いかを調べてみました。

Continue reading

PHPでGZIPのファイルを解凍する

  • Posted by: zaru
  • 2008年1月 8日 16:17
  • PHP

HTTP/Request.php を使ってぬるぬると色々なサイトのヘッダーを覗いてファイルをダウンロードするスクリプトを書いていたら、ダウンロードしたのは良いけど正常に開けない、壊れたファイルになってしまう事があった。

ヘッダを見てみると content-encoding が gzip になっていました。Webサーバから送信するときに圧縮してやるアレです。なので、ダウンロードしたファイルが gzip だった場合に解凍する方法をメモ。

Continue reading

誰だったかのechoとprintの使い分け

  • Posted by: zaru
  • 2008年1月 7日 11:04
  • PHP

echoとprintの違いと使い分けで、echo と print についての違いと、使い方について書かれています。僕も大分前にこの違いってなに?って思っていたので非常に助かりました(自分で調べろよ)。

そして、昔に読んだPHP解説本で echo と print の使い分けについてアドバイスをしていたのを思い出しました。たしか…

  • print を本番用出力/echo をデバッグ用出力として使い分ける(逆も可)
  • 本番リリース時には一括置換で echo の行をコメントアウトする

といったものでした。

まぁ、今思えば逆に面倒くさい&トラブルの元になるような気もするのですが、こんな考え方もあるのかと当時は感心した記憶があります。

PHPで数値判定する時はご注意を

  • Posted by: zaru
  • 2007年12月 6日 19:20
  • PHP

非常に参考になるエントリ「そのis_numeric()は適切ですか?」を読んで。PHPで数値判定する機会は大分あると思う。特にフォームで入力された電話番号やらなんやらで。その判定方法を間違ってしまうと、思わぬバグが発生してしまうという話。

Continue reading

MySQLのAUTO_INCREMENTで生成された値を簡単に取得する方法

MySQLでテーブルのキーとなるカラムをAUTO_INCREMENTにするのはよくある事で、データをInsertしてから、InsertしたレコードのAUTO_INCREMENT値を取得したいというのもよくある事で、どうやるのが一番ベストか悩んだ時期がありました。

Continue reading

PHPのopen_basedir設定:Pleskで管理されているサーバ

  • Posted by: zaru
  • 2007年9月15日 14:32
  • PHP

Pleskで管理されているVSPのサーバで、php.iniをいじってもなぜか open_basedir の設定が反映されなくて困っていたら、他の場所に設定ファイルがあった。

そもそもPleskのデフォルト設定だと

php_admin_value open_basedir "/var/www/vhosts/ドメイン/httpdocs: /tmp"

になっていて、あんまり意味ないんじゃない?というか普通に使いにくい。

この設定ファイルは

  • /var/www/vhosts/ドメイン/conf/httpd.include

にある。このファイルの該当部分を

php_admin_value open_basedir none

に書き換えれば open_basedir がオフになる。

PHPの変数をトレースソフト「HTTPTrace」の文字コードについて

  • Posted by: zaru
  • 2007年8月28日 18:10
  • PHP

PHPで、変数の中身をじろじろ見たい欲求に最近かられてて、いいツールはないものかと模索中だったところ、ぴちぴちで使いやすいツールがありました。

その名も「HTTPTrace」。Windows環境でクラインアントソフトが動作し、スクリプトにライブラリを読み込んでたった1行コードを追加するだけで、クライアントソフトに変数の中身が放り込まれていきます。

表示も非常に見やすく、導入も簡単とあれば使わないわけにはいかない。すでにPHP の変数をトレースする HTTPTrace をちょっと改造してみたで、改良案が出ており、magiwoさんもこれを反映するとのことなので期待大。

ただ、個人的にはスクリプト側の文字コードを設定できれば…と思いました。

現状ではマルチバイトコードは、UTF-8の文字コードしか正常に表示されないので(ですよね?)、EUCを使っている場合は、htrace.php の function _ExportValue() を少しいじくってやればOK。

詳細な導入方法については

が参考になるかと思います。

って改造ソースも示さず終わるのはアレなので、続きを読むでいじった部分を紹介します。

Continue reading

MySQLとPostgreSQLの日付フォーマットの違い

  • Posted by: zaru
  • 2007年6月20日 12:35
  • PHP

久々に PostgreSQL をさわることになって、タイムスタンプから2006年のレコードだけを抜き出したいなーとSQLを書こうとしたら、そういえば PostgreSQL では、タイムスタンプを指定したフォーマットで返す関数はなんなんだろ、と思ったので、MySQL と PostgreSQL でよく使われると思われる日付フォーマット表を作ってみた。

Continue reading

MySQLだけで文字列を一括置換する

  • Posted by: zaru
  • 2007年6月 1日 19:38
  • PHP

MySQLで特定の文字列を全レコード一気に置換する方法。

今まで、PHPやPerlでレコードを取得して、スクリプトで置換して UPDATE していたけど、実はMySQLだけで一気に置換ができることが判明。

Continue reading

PHPでCSVファイル読み込みでエラー

  • Posted by: zaru
  • 2007年5月23日 19:31
  • PHP

カンマ区切りのCSVファイルをアップロードし、fgetcsv() を使って解析するスクリプトを組んでいたら色々なことではまってしまった。

そのエラー内容と、対処法。

Continue reading

PHPに関するアンケート

  • Posted by: zaru
  • 2007年5月17日 09:35
  • PHP

PHPのテクメモさんで、PHPに関するアンケートを行っています。個人的にも興味があるので、PHPを使っている方は是非アンケートに答えてください。

期限は2007年5月31日。

ちなみに、16日までのアンケートでいくつかのアンケート結果ダイジェストも出ている。

スマートに、そして極端に短く組むプログラマー大会

  • Posted by: zaru
  • 2007年5月10日 16:40
  • PHP

プログラミングとは、同じ動作をしていてもプログラマーによって中身は全く違うものになる。人によってコーディングのポリシーは色々とあるだろうけど、とにかく短くコーディングしようぜ!っていうのを競うサイト。

あるお題にそったプログラムを組み、アップロードし動作が成功していればランキングに名を連ねられる。目指すのは誰よりも短いプログラム。もちろんソースは公開されていないので、上位のプログラマーがどんなテクニックを使っているか想像するだけでワクワクする。

とんちっぽい問題もあって、テクニックだけじゃなく発想の転換が必要だったりと面白い。仕事で疲れたとき、勉強・研究などにぜひどうぞ。

僕も一応参戦中。まだ、2つしか挑戦できていないけど。

Continue reading

日付・時刻処理を簡単にする方法 - PHP

  • Posted by: zaru
  • 2007年4月25日 15:14
  • PHP

WEBアプリケーションを作っていて頻繁に使う日付や時刻のいろいろな処理。国や文化・作っている人によってさまざまなルールが存在するけど、PHPを使えば(たぶん)簡単に実現できてしまう。

Continue reading

配列の値をランダムに抜き出す方法 - PHP

  • Posted by: zaru
  • 2007年4月19日 09:29
  • PHP

array_rand() を使えば、指定した数だけ値を配列からランダム取得することが出来る。PHP 4.2.0以降は、srand() を使う必要はない(自動化されている)。

$array = array_rand($array,5);

ってやればいいのかと思ったら、array_rand()は配列のキーをランダムに返す仕様。

なので、値を取得したい場合は

$keyArray = array_rand($array,5);
foreach($keyArray as $key){
	print $array[$key];
}

とやる必要がある。

その他に、shuffle()という関数もあるが、配列のキーで廃棄されてしまうので連想配列の場合は array_rand() にした方が良いかもしれない。これはあとで検証。

ちなみに、srand() を使用する場合は

srand((float)microtime() * 1000000);

PHPで読み込み中のページにデータを逐次出力する方法

  • Posted by: zaru
  • 2007年4月18日 09:56
  • PHP

時間のかかるページや、むしろ時間をかけて表示したいページで逐次データをブラウザに出力したい場合は、flush() を使う。が、ブラウザやサーバ・PHPの設定によっては上手くいかないのでメモ。

mb_output_handlerが設定されているとflush()だけ呼び出しても、標準出力(=Web応答)に出力されません。 ob_flush()だけ呼び出してもおんなじです。

PHPの整理とは無縁なメモ書き

というわけで

ob_flush();
flush();

とやると上手くいく。

出力バッファ系に関しては、ここを見ると分かりやすいかもしれない。

メールアドレスを正規表現で判定する方法

  • Posted by: zaru
  • 2007年4月16日 10:35
  • PHP

WEBプログラムを作っていると、たびたび出てくるメールアドレス入力フォーム。そのメールアドレスが正しいかどうか判定する方法。

Continue reading

2バイト文字列を文字化けせずに切り抜く方法 - PHP編

  • Posted by: zaru
  • 2007年4月11日 14:53
  • PHP

長い文字列を適当な長さに揃えて出力したいときに、2バイト文字と1バイト文字が入り混じっていると、中途半端に文字がカットされ、文字化けしてしまうのを防ぐ方法。

//文字コード設定
mb_language("Japanese");
mb_internal_encoding("EUC");

$str = 'あいうえおAbcdかきくEfghけこさしすせそ';

//最初から10文字を切り抜く
$str = mb_substr($str,"0","10");

mb_substr() だけだと文字コードをきちんと認識せず語尾が文字化けしてしまったので、mb_language() と mb_internal_encoding() を使ってきちんと設定すると綺麗に切り抜ける。

英字入りの日時フォーマットを変換する

  • Posted by: zaru
  • 2007年3月22日 07:26
  • PHP

ブログのRSSデータを解析しているときに、英字入りフォーマットで困ったのでメモ。

Tue, 20 Mar 2007 10:14:58 +0900 のような英字入りの日時フォーマットを 2007/03/20 10:14:58 みたいに好きな日時フォーマットに変換する方法。

//英文形式の日付をUNIXタイムスタンプに変換する
$date = strtotime("Tue, 20 Mar 2007 10:14:58 +0900");

//UNIXタイムスタンプを好きなフォーマットに変換
$date = date("Y-m-d H:i:s",$date);

strtotime() と date() を使うことにより好きなフォーマットに変換できる。

ブログRSSデータを取得・解析するPHPライブラリ

  • Posted by: zaru
  • 2007年3月20日 10:14
  • PHP

ブログのRSSデータを取得して解析する必要が出てきたので、簡単だしちゃちゃっと組もうかなーと思ったけど時間もないのでライブラリを探すことに。

RSSファイルのURLを指定して、file_get_contents()/fread(), cURL, 外部コマンド の3通りから取得方法を選べるライブラリ。使い方も簡単ですぐに組み込める。使おうと思っていたサーバは cURL関数が未サポートだったので、file_get_contents()を使用した。

PHPで今月が何日あるかを調べる

  • Posted by: zaru
  • 2006年12月18日 22:17
  • PHP

プログラムを組んでいるとき、指定した月が何日あるのかを知りたいことが結構あるのでメモ。

date()を使う

普通のホスティングサーバであればこの方法。

<?php
	$timestamp = mktime($hour,$minute,$second,$month,$day,$year);
	print date("t",$timestamp);
?>

date("t") で指定したタイムスタンプの日数を得ることができる。もちろん、あらかじめ mktime() でタイムスタンプを取得しておく必要がある。

cal_days_in_month()を使う

カレンダー関数が組み込まれていれば cal_days_in_month() を使うのが一番簡単。自分でいじる権限があるサーバであれば、コンパイルするときに --enable-calendar のオプションを付け加えれば使用できる。

<?php
	print cal_days_in_month(CAL_GREGORIAN,$month,$year);
?>

速度・負荷的にどちらが優れているかは未検証。

個人的希望は、国が毎年毎年の祝日データを XML で提供してくれれば祝日も完璧なカレンダーが作れるんだけどなぁ。

PHPの設定を htaccess でやろうとしたら反映されない

  • Posted by: zaru
  • 2006年12月 1日 19:04
  • PHP

htaccessのイメージ

特定のディレクトリだけPHPの設定を変える必要が出てきて、久しぶりに htaccess を使ってみたら、どうしても変更が適用されないという事態に遭遇。

htaccess 自体が許可されていないかと、Apache の httpd.conf を確認しても AllowOverride は All になっているし、じゃあ今度は htaccess の書き方が間違っているのかと ErrorDocument とか別の設定を書き加えたら、きちんと動作しているし…。

じゃあじゃあ、この htaccess を別のサーバに持っていってみるか!と思って、持っていったら、あっさりPHPの設定が変わっている…。

こうして、うんうん数十分悩んで、悩みぬいて飽きてきてコーヒーを飲みながら Google で調べていたら、致命的な落とし穴を発見。

PHP の Apache2 におけるモジュール名

(略)

ただし Win32 と FreeBSD では以下の通り。

>>> for apache 2 under freebsd (not sure about other systems) it should be
>>> <IfModule sapi_apache2.c>
>>> ...
>>> </IfModule>
Same for Windows

親方、空から覚え書きが!

そう。今回使っているサーバは、正真正銘 FreeBSD 。前に使っていたのは Linux 。どうりで…ね。

SSL内だとファイルのダウンロードができない

  • Posted by: zaru
  • 2006年11月28日 10:42
  • PHP

ダウンロードのエラー表示

https で始まるURL、つまりSSL内でファイルをダウンロードするPHPを組んだのだけれど、Windows の Internet Explorer で実行すると上の画像のようなエラーが出てきてしまう。

Internet Explorer では、www.example.co.jp - command.php をダウンロードできません。このインターネットのサイトを開くことができませんでした。要求されたサイトが使用できないか、見つけることができません。後でやり直してください。

って感じで。

FirefoxやSafariだと問題ないのにー…とか思いつつ、調べてみたら原因はこれだった。

Internet Explorer を使用して下記条件を満たすファイルを開いた場合、ファイル名が見つからない内容のエラーが発生し、ファイルを開くことができない場合があります。

  • ダウンロード対象となるファイルに Content-Disposition:attachment ヘッダーを付加している
  • Cache-Control:no-cache ヘッダーなどを使用して、ファイルのキャッシュを行わない設定をしている

Content-Disposition: attachemnt と Cache-Control: no-cache によるダウンロードの問題:Microsoft

session_start() をする前に、session_cache_limiter('public') を使って、キャッシュを許可するように設定すればエラーを回避することができる。

PHPコード最適化12のコツ

  • Posted by: zaru
  • 2006年11月21日 12:31
  • PHP

PHPをコーディング・設計する際に12個のことに気を使えば、もっと早くなるという記事があった。

  1. If a method can be static, declare it static. Speed improvement is by a factor of 4.
  2. Avoid magic like __get, __set, __autoload
  3. require_once() is expensive
  4. Use full paths in includes and requires, less time spent on resolving the OS paths.
  5. If you need to find out the time when the script started executing, $_SERVER[’REQUEST_TIME’] is preferred to time()
  6. See if you can use strncasecmp, strpbrk and stripos instead of regex
  7. preg_replace is faster than str_replace, but strtr is faster than preg_replace by a factor of 4
  8. If the function, such as string replacement function, accepts both arrays and single characters as arguments, and if your argument list is not too long, consider writing a few redundant replacement statements, passing one character at a time, instead of one line of code that accepts arrays as search and replace arguments.
  9. Error suppression with @ is very slow.
  10. $row['id'] is 7 times faster than $row[id]
  11. Error messages are expensive
  12. Do not use functions inside of for loop, such as for ($x=0; $x < count($array); $x) The count() function gets called each time.

12 PHP optimization tips:Alex Moskalyuk Blog

PHP4ではClass化することは滅多にないので(1)〜(2)は無視するとして。

(3)の require_once()が遅い(というかメモリを消費するという意味かな)というのは気になる。include_once()のが良いってことなのかな。

さらに(4)で、インクルードするパスは絶対パスが有利…と。まぁ、これは当然かな。

普通はインクルードするディレクトリを define() で定義して、include_once(INCLUDE_DIR . "xxx.php"); とかってやるのが良い感じ。

(5)は気にしない。

(6)の正規表現よりも strncasecmp() / strpbrk() / stripos() を使えっていうのは、理解できるんだけど、正規表現が楽すぎて、ついつい早さよりも優先してしまうなぁ。

(7)は strtr() >> preg_replace() > str_replace()。str_replace() よりも preg_replace() の方が早いっていうのは意外。単純な置換の時は strtr() を使えってことか。

(8)はちょっと理解できなかった。配列か配列じゃないかを自動で判定させるのは良くない…?ってことか。

(9)は関係ないのでパス。今時いるのかな、@でエラー制御する人。

(10)は有名な話。配列のキーを、シングルクオートで囲む・ダブルクオートで囲む・なにも囲まないでは、処理スピードが違う。シングル > ダブル > 囲まない の順番。ただ、実験してみると大きいスクリプトでない限り差は顕著に見られない。けど、可読性とバグ・エラー潰しのために囲っておくが吉。

(11)は、PHPのエラーメッセージは重いよって話。本番環境なら当然。

(12)は、PHPに限らず色々な言語に共通する。for() で毎回計算しなくてはならない場所に、さらに関数を入れて計算させると遅くなるよ、と。for() で回す前に、あらかじめ計算して数値を出してから。

ほとんど基本的なことだけど、こういう地道な気配りがパフォーマンスの向上につながる…と思う。設計さえ良ければ。

PHPでファイルのダウンロードをするスクリプトで見落としていた…

  • Posted by: zaru
  • 2006年10月 4日 19:23
  • PHP

system()関数を使って、zipコマンドで圧縮したZIPファイルをダウンロードさせるPHPスクリプトを組んでいたら、ダウンロードダイアログが出ずに、ブラウザ側に出力されてしまって悩むこと20分。

PHP側の設定を見直したり(zlib.output_compression = Offなど)、headerの出し方が間違っていないか、何通りもの組み合わせを試してみたりしたけど全然ダメ。

半ばあきらめかけたところで、何気なく吐き出されているものを見てみたら先頭にupdating: aaa.csv (deflated 75%) の文字列!

やべーsystem()関数でzipコマンド使うと、どれだけ圧縮できたかリターンされるんだった…。ここんところ使っていなかったsystem()関数だったから盲点。

system("zip aaa.zip aaa.csv > /dev/null");とすることで決着。あーもっと視野を広くもたなくちゃ。

桁数の決まっている数字列でインクリメントしたい

  • Posted by: zaru
  • 2006年3月27日 20:17
  • PHP

0001、0002、0003と桁数があらかじめ決まっている数字をインクリメントするには以下の方法がある(他にもあるけど)。

str_padを使う方法

$num = '0010';
$num++;//$numは 11 になっている
print str_pad($num, 4, "0", STR_PAD_LEFT);//ここで 0 を左側に埋める

Perlと違いPHPでは $num++ とインクリメントすると型変換が行われ、先頭のゼロが消される。なので、str_padを使って左側に指定の桁数になるまでゼロを埋める必要がある。

PHPでExcelファイルを作成する

  • Posted by: zaru
  • 2005年10月11日 16:12
  • PHP

会社のWEBサイトに掲載しているクライアントに向けて、アクセスレポートというものをPDFデータで提出してるんだけど、クライアント数が100以上で、WEBサイト自体も複数あるので、数百のレポートファイルを作成しなくてはならないのが非常に憂鬱。

作業しているのは僕ではなく、別の子なんだけど、それだけで毎月1週間くらい作業に追われているのがかわいそうで、なにか良い方法は無いかと模索していたら、PHPからExcelファイルに出力するライブラリがある事を発見。(当初はExcelのマクロを作成して、アクセスデータが格納されているDBから自動的に吐き出す予定だったんだけど、予算の都合上なしに)

Spreadsheet_Excel_Writer

Pearで配布されていて、導入も簡単。操作方法も非常に単純で、関数も使えるのでへたにマクロを組むよりも汎用性が高い気がする。こいつとjpGraphを使ってレポートを作成したら一発で数百のファイルが作成出来た。

  1. DBからアクセスデータを生成
  2. jpGraphでグラフをJPEG画像作成
  3. djpegコマンドでBMP形式に変換
  4. Spreadsheet_Excel_Writerでグラフ&データを出力

あとはこのExcelファイルをPDFデータに変換出来れば完璧 :D なんか良い方法ないかな?

PHP青マンモス本

  • Posted by: zaru
  • 2005年7月 7日 04:46
  • PHP

有名なPHP解説本であるマンモス本「PHP5徹底攻略 エキスパート編」が出たようです。PHP4の続編という形なのだけれども、かなりの量になってます。「PHP4徹底攻略 実戦編」の約2倍のページ数です。

PHP5にしぼった内容になっているのかな?それとも、PHP5にこだわらず実践的なテクニックが書かれているのかな。早くPHP5が一般的なホスティングサービスに浸透しますように :)

PHPでよく間違えること

  • Posted by: zaru
  • 2005年7月 1日 00:19
  • PHP
if(isset($data){
処理;
}
if(preg_match("/^[0-9]$/",$data,$match){
処理;
}

本当に、よく間違えるんです。

PHPでセッション管理

  • Posted by: zaru
  • 2005年5月15日 23:10
  • PHP

今まさに仕事でやっていて気が付いたメモ。というか、今までなんで使わなかったんだろう?と思ったりもする初歩的な部分 :(

PHPでセッションを使うときに、スクリプトによっては、セッションを混同させたくない場合がある。例えば、a.phpでは $_SESSION['test'] に「a」という文字列を、b.phpでは $_SESSION['test'] に「b」という文字列を保存しておきたい場合だ。

a.phpコード
session_start();
$_SESSION['test'] = 'a';
b.phpコード
session_start();
$_SESSION['test'] = 'b';
c.phpコード
session_start();
print $_SESSION['test'];

これだと、当然a.phpにアクセスすれば、$_SESSION['test']に「a」が、b.phpにアクセスすれば$_SESSION['test']に「b」が入る。

これを住み分けるにはsession_name()を使う。これで、セッションの名前を設定してやれば、それぞれのスクリプトで違ったセッションを使うことができる。

a.phpコード
session_name("aaa");
session_start();
$_SESSION['test'] = 'a';
b.phpコード
session_name("bbb");
session_start();
$_SESSION['test'] = 'b';
c.phpコード
session_name("aaa");
session_start();
print $_SESSION['test'];

こうすると、c.phpにアクセスした場合は、a.phpの$_SESSION変数のみが表示されるようになる。

PHPとvsftpdは相性が悪い?

  • Posted by: zaru
  • 2005年5月 7日 11:08
  • PHP

非常に気になる記事を見つけたのでメモ。

vsftpdで立てられたFTPサーバに、ftp_put()関数で連続的にファイルをアップロードすると数分の1の確立でコネクションが切断された。

接続経路が悪いのか、単純に設定が悪いのかは分からないけど、別のproftpdが稼働しているサーバを利用した場合には再現しなかったのでvsftpdが悪いと言う事にしておく。

なんちゃって電器店

僕は業務でまさにPHP+vsftpdの環境を使っているので、出社したら試験してみなくては。これは、クライアントのPHPから、外部のvsftpdサーバに接続したという事なのかな。

個人的にはProftpdが好きで使っていたんだけれども、最近のディストリビューションに入っているのがvsftpdなので、なんとなく使っています。パッケージだからセキュリティパッチの適用とか楽だし :P

Index of all entries

Home > PHP Archive

Profile

zaru

Name : zaru

Webプログラマ+Webデザイナで、Webディレクタやってます。Twitterやっているので、ぜひフォローしてやってくださいませ。Twitter - zaru。また、そのほかのプロフィールについては、iddy - zaruを見てください。

Search
Feeds
Others

Return to page top