※ パクレゼルヴではWeb開発エンジニアを大募集中!詳細はこちら

Archive

Archive for 2008/10

PHPのデバッグ方法  

2008/10/31 金曜日 21:27:15

またまたチョコボールです。

趣味で運営してるサイトはロリポップサーバーを利用してますが、
割と最近PHPがバージョンアップしてPHP5に切り替え可能になりました。

自動的にPHP5になるのかと思ってひやひやしていましたが、管理画面から切り替え可能という形でした。
そりゃそうですよね。。

で、近日、切り替え作業をしようと思ってます。

仕事での開発環境はPHP5なので当たり前のように使っていたfile_put_contents関数ですが、PHP4で使えなくてマジっすかと思った記憶があります。
PHP4ではfopenしてfwriteしてfcloseする必要があります。

ということでfile_put_contents関数等を使ったデバッグ方法を。。

コーディング中、最も簡単なデバッグ方法は

 echo $data;

とか

 echo "<pre>";
print_r($data);
echo "</pre>";

とか

 echo "<pre>";
var_dump($data);
echo "</pre>";

ですかね。。

それ以降の処理をストップしてデバッグしたければ直後に

exit;

なんかを書けばいいと思います。

ただ、画面では表示されない処理のデバッグをしたい時やデバッグ内容やエラーログをテキストに記録したりしたい時があるので下記のような関数を作って使ってます。

■画面にデバッグ表示

function _debug($str, $showHtml = false){
	echo "<pre>\n";
	$ret = print_r($str, true);
	if($showHtml){
		$ret = str_replace('< ', '&lt;', '&gt;', $ret));
	}
	echo $ret."\n";
	echo "</pre>\n";
}

$strに<hr />などのHTML的に特殊な意味をもつ文字列が入っていた場合、デバッグ内容がうまく表示されないので、
そのような時は第二引数にtrueを入れてやると特殊文字をHTMLエンティティに変換して表示させます。

■ファイルに追記してデバッグ

function _log($str, $type = 'debug', $file_name = null){
	if(is_null($file_name)){
        $file_name = LOG_DIR.'/'.$type.'_'.date('Ymd').'.log';
	}
	$data = date('Y/m/d H:i:s').' '.print_r($str, true). "\r\n";
	file_put_contents($file_name, $data, FILE_APPEND | LOCK_EX);
}

※LOG_DIR→ログが出力されるディレクトリのパスの定数

上記で日ごとにログが取れます。

ただ、このままですと直接ファイルにアクセスされかねないので、
http://labs.pakureserve.jp/archives/90
のように
.htaccess
を利用して指定拡張子をアクセス出来ないようにしたりの工夫が必要ですね。

次は、弊社システム開発部、のびーにょサブマネージャーから教えてもらったデバッグ方法です。

mail(’【デバッグを受け取りたいメールアドレス】’, __FILE__.’:’.__LINE__, print_r(【変数や配列等】, true));

これはすごく便利。。。

削除し忘れて放置するとメールボックスがすごいことになりかねませんので要注意です。笑

明日、弊社、設立3年目になるようです。

今後とも宜しくお願い致します。

MoriMoriMoriMori PHP

キーパーソン  

2008/10/31 金曜日 20:59:20

お疲れ様です

のびーにょです。

プログラムってちょっと書けるようになると結構いろいろ出来るような気になりますよね。
でも、既存のソースの修正であったり追加であったりなんかだと、追加の方がはるかに楽だったりしますよね。
修正の場合は何処がどのようになっているかをある程度把握しなければなりません。
追加でもそうですけど、データ追う量が全然違いますよね。

と、いうかですね。
修正する場合はその周りのソースを8割ぐらい理解した方がいいと思う訳ですよ。
そうすれば次の修正や追加の時に作業が軽減できますし、そのソース(システム)に精通した人になれます。

ま、何しててもそうだと思いますけど、いかに自分のポジションを良い状態に持っていけるかってのは会社、社会で働いて生活していく上では結構重要なことだと思います。

別に出世がどうとかじゃなくて、少しでも働きやすい、生活しやすい、”楽しい”状態に持って行くにはそういう重要な人(キーパーソン)になるのがお勧めです。

で、プログラマなら重要なシステムに精通している、管轄しているって言うだけでも結構そういう位置に行きやすいですよね。
たとえば、『あのシステムと●●社のシステム繋ぎこみして新たな事業展開をしたい』ってなったとするじゃないですか。
で、そのシステムに一番詳しい人に(別にリーダーじゃなくてもいいわけですよ)聞きに来たり、その人呼んで会議したりしますよね。
だから機能を限定して、この部分ならこの人が一番詳しい みたいな人になるのから始めてみるのがいいんじゃないかなぁと思います。
そのポジションで学べることもたくさんあります。

でも、さっさと全体を見た方がいいと思います。個人的にですけどね。
ポジションが人を育てる 
って言うのは間違ってないと思っていますので。

のびーにょ その他, システム

csvファイル出力関数  

2008/10/31 金曜日 19:22:57

チョコボールです。
あと一か月働けば実務経験1年です。

前回csvファイルの一般的な書式について書きましたが、

その続きとして、DBから引っ張ってきたデータをCSV出力する関数を作ってみました。

例えば

+----+--------+-------+
| id |   name | level |
+----+--------+-------+
|  1 |  quest |    50 |
|  2 | arthur |    45 |
|  3 |  maria |    35 |
+----+--------+-------+

のようなテーブルが有り、これらを全て引っ張ってきてごにょごにょして下記のような配列に格納するとします。

$header(1行目の項目名)
Array
(
	[0] => ID
	[1] => 名前
	[2] => レベル
)
$data(データ部分)
Array
(
	[0] => Array
		(
			[id] => 1
			[name] => quest
			[level] => 50
		)

	[1] => Array
		(
			[id] => 2
			[name] => arthur
			[level] => 45
		)

	[2] => Array
		(
			[id] => 3
			[name] => maria
			[level] => 35
		)
)

これら配列を下記の関数に渡してやります。

downloadCsv($header, $data, 'member');
function downloadCsv($header = array(), $data = array(), $prefix = '')
{
	$ret = '';
	// ヘッダー(1行目の項目名)がある場合
	if(count($header) > 0){
		foreach($header as $val){
			//「"」は「""」に置換してエスケープ
			$tmp[] = str_replace('"', '""', $val);
		}
		$ret .= '"'.implode('","', $tmp).'"'."\r\n";
		unset($tmp);
	}

	foreach($data as $val){
		foreach($val as $vval){
			$tmp[] = str_replace('"', '""', $vval);
		}
		$ret .= '"'.implode('","', $tmp).'"'."\r\n";
		unset($tmp);
	}

	// 文字コードを変換
	$ret = mb_convert_encoding($ret, 'SJIS', 'UTF8');

	// 出力する際のファイル名
	$file_name = $prefix.date('Ymd').'.csv';

	// HTTPヘッダ出力
	Header("Content-Disposition: attachment; filename=${file_name}");
	Header("Content-Type: application/octet-stream; name=${file_name}");
	Header("Cache-Control: ");
	Header("Pragma: ");

	// データを出力
	echo $ret;
	exit;
}

member20081031.csvみたいな感じでDLできると思います。

もちろん、ソース内コメントの「文字コードを変換」部分は内部文字コードに合わせて変更しないとCSVが文字化けしてしまいます。
上記はUTF-8の場合です。

あと、バッファーに何か入ってる場合(デバッグ出力文字等)、その文字もCSVに出力されてしまうので、一番最初の行に

ob_end_clean();

を追加して出力のバッファリングをオフにすると良いです。

一度軽くハマったんですが “\r\n” は ‘\r\n’ じゃ駄目です。
文字列として認識してしまいますので。
ダブルクォートで囲んであげましょう。

MoriMoriMoriMori MySQL, PHP, データベース

ExcelVBAちょこっとメモ  

2008/10/29 水曜日 20:17:49

こんばんわ。かーつんです。

今回はちょっとしたツール作った時のメモをば。

Excelファイル選択ダイアログを出して、選択されたファイル名(パス付)をセルに格納する場合
こんな感じに、GetOpenFilename()を使う。

Private Sub selectFile()
	Dim FileName As String
	'-- ファイル名取得 --
	FileName = Application.GetOpenFilename("Microsoft Excelブック,*.xls")
	If FileName = "False" Then
		Exit Sub
	End If
	ActiveWorkbook.Sheets(1).Cells(1,1).Value = FileName
End Sub

「キャンセル」されたときは【False】が返ってくるからSubを抜けるようにしてエラー回避する。
ファイル名のみ欲しいときはFileNameを分割すればOK

フォルダを選択させて、フォルダ名(パス付)をセルに格納する場合
こんな感じに、FileDialog()を使う

Private Sub selectFolder()
	Dim Folder As String
	'-- フォルダ名取得 --
	With Application.FileDialog(msoFileDialogFolderPicker)
		If .Show = True Then
			Folder = .SelectedItems(1)
		Else
			Exit Sub
		End If
	End With

	ActiveWorkbook.Sheets(1).Cells(1,1).Value = Folder
End Sub

キャンセルされてもこいつは【Falseを返さない】。
調べるの面倒なので、選択されたときには結果を取得して、
それ以外はエラーでSubを終わらせてみた。

もっとスマートな書き方とかありそうだけど、
今回はツールなので、時間勝負ということで。。。

以上、ちょこっとメモでした。

かーつん その他

私SQL  

2008/10/24 金曜日 16:02:19

mysqlにはmysqldumpとかいう便利なバックアップ機能がついています。

mysqldump --all-databases -uユーザー名 -pパスワード DB名 > 保存ファイル名.sql

とすると、そのサーバーのDB全てが保存ファイル名として保存されます。
--all-databasesと指定すると、DB、テーブル、レコード全てが出力されます。
ここのパラメーターを変更することで、テーブルのみとかレコードのみとか指定できます。

よく使うパラメータは以下のとおり。

-A、--all-databases
	全てのデータベースを指定。
-B、--databases
	出力するデータベースを指定する。
-t、--no-create-info
	CREATE TABLE情報を残さない。
-d、--no-data
	レコードを残さない。

こんな感じで、手軽にバックアップができます。
で、戻す方法は・・

mysql -uユーザー名 -pパスワード DB名 < 保存ファイル名.sql

出力の時に使った「>」を「< 」とするだけで、入力できるお手軽さ。

ちなみに、mysqldumpのデフォルト文字コードはUTF-8のようで、環境によっては文字化けてしまう場合があるので、出力の際に「--default-character-set=文字コード」パラメータを追加することで、指定の文字コードに出来るようです。
そんな感じ。

下音タヌキ MySQL