ようこそゲストさん

CPA-LABテクニカル

メッセージ欄

2008年1月の日記

2008/01/28(月) 変数の代入は、値のコピーにあらず-PHP変数管理 (3)

前回の変数管理の基礎(PHPの参照とは何か) でシンボルテーブルについて説明した。これがわかっていないとPHPの変数管理はわからない。


今回は、もっとも基本的な変数の値の代入、について説明する。
code1
$a=$b

なぜ、こんな単純なことをいちいち説明しなければならないのか。

続きを読む

  • issetを正しく理解する。null値とunsetの違い-PHP変数管理 CPA-LABテクニカル spok
    nullほど人を惑わすものはないだろう。設定されてない値ってなんだ?unsetされた変数とは違うの?様々な疑問があろう。ここで、明確な理解をしておきたい。(PHPの場合)シンボルテーブルのおさらい以前に変数管理の基本として書いたけれども、PHPは、シンボル...

2008/01/27(日) 変数管理の基礎(PHPの参照とは何か)-PHP変数管理 (2)

内部構造がわからず、もやもやとした気分でコーディングするのは、あまり気分が良くない。
PHPの変数管理の詳細を知ると、複雑な参照代入や配列などの使い方の幅が増えてくる。はず、ということで、いろいろ調べてみた。変数や関数の受け渡しについては知っているつもりで、間違った知識で書いていることも多いことがわかり、自分でもあぜんとした。ので、いくつかわかった(つもり)のことを書いてみる。

続きを読む

変数管理はワンクッションあり→シンボルテーブル

PHPで、$a='one';と書いた場合、内部的に 変数名a → 値one という単純な表が作られるわけではない。「変数名aは、値の格納庫コンテナ(zval構造体)No.#0001と対応している」というシンボルテーブルが作られ、格納庫(zval)No.#0001にoneという値が書き込まれる。
code1
$a='one';

figure1  $a='one'; で作成されるPHP内部の変数管理表
シンボルテーブル
変数名格納庫(zval)No.
a#0001

格納庫(zval)
No.valuetype
#0001onestring(文字列型)
格納庫zvalについては別ページで改めて説明する。

参照代入とは  -シンボルテーブルの多重割り当て


シンボルテーブルには、同じ格納庫(zval)No.に、複数の変数名が割り当てられることがある。それが参照代入と呼ばれる。
例えば、以下のコードは、同じ格納庫(zval)No.にa,bの変数名が割り当てられる。
code2
$a= <span style="color:red;font-weight:bold;">&</span> $b; 
figure2  参照代入された後
シンボルテーブル
変数名格納庫(zval)No.
a#0001
b#0001

格納庫(zval)
No.type
#0001onestring
このような構造だからこそ、
code3
$a='one';
$b= & $a;
$b= 'two';
としたとき、同じ格納庫(zval)No.に書き込まれるわけだから、$a,$bともに two となる。
ここで実体と呼ばれる、スカラー値が入った格納庫zvalは、決してコピーされていないことに注意する。実体はただ1つ。上の例では、その1つの実体をを呼ぶのに$aとも$bとも使われるわけだ。

C言語のポインタとの違い

ここが、C言語のポインタと違うと言われる理由である。C言語のポインタと同じものでであれば、以下のようになっているはずである。

figure3
シンボルテーブル
変数名格納庫(zval)No.
a#0001
b#0002

格納庫(zval)
No.type
#0001onestring
#0002#0001(long?)
※もし、PHPの参照代入がC言語のポインタと同じだったらの例示

この違いを理解しておかないと、後々、いろんなところで、「はまる」ことになる。

$aと$bは等価である。($a =& $b)  -ただし、$a,$bがオブジェクトの時は除く

以下のコードは同じ結果となる。$aと$bは等価である。
code4
$a='one';
$b= & $a;
$a= 'two';

code5
$a='one';
$b= & $a;
$b= 'two';

結果は以下のとおり。

figure4
シンボルテーブル
変数名格納庫(zval)No.
a#0001
b#0001

格納庫(zval)
No.type
#0001twostring

誤解されがちなのは、=&演算子が、参照「代入」と翻訳されていることから、$b=& $a;としたときに、まるで、$bに何かの値が書き込まれるような感覚になることである。それはCのポインタであり、PHPの参照とは違うことをよく理解する必要がある。あくまでも、PHPの参照代入は、結びつけるべき左辺の変数名をシンボルテーブルに追加することである。シンボルテーブルを利用して、変数名と格納庫(zval)Noを新たに連動させる、ということである。
誤解を恐れずにいえば、$b=& $a;の場合、$bの実体(zval格納庫)はないのだ。もう少し正確にいえば、$aの実体を間借りするようなものだ。この間借りすることをもって、エイリアスという言い方をする人がいるようだ。もっと正確にいえば、$aと$bは等価なので、$aの実体を$bの実体としても扱う、ということになる。


ただし、上記は、オブジェクトの時だけは異なった結論になる。それは、のちほど説明したい。

unset と =null の違い

では、ここでunset($a)としたら、どうなるか。
$a=null;とどう違うか、検証する。

まず、$a=nullであれば、格納庫(zval)No.#0001にnull値が書き込まれるわけだから、$a,$bともにnullとなる。$a,$bは連動しているのだ。

ではunsetはどうだろうか。
code6
unset($a);
unsetは、「変数を破棄する」でない。「シンボルテーブルからその変数名を削除する」という動作をする。つまり、
figure5
シンボルテーブル
変数名格納庫(zval)No.
a(削除)#0001(削除)
b#0001

格納庫(zval)
No.type
#0001twostring


となるので、$aはなくなってしまうが、$bの値はtwoのままである。

つまり
code7
$a='one';
$b= & $a;
$a= 'two';
unset ($a);
とすると、$bの値は、 two となる。

Ohhh!まるで、$bが$aをヤドカリのように乗っ取ってしまったようだ。

まとめ

このようにPHPでは、変数の名前とその値は切り離されており、シンボルテーブルがそれを結びつける働きをしている。シンボルテーブルでは、複数の変数名に対して、同じ実際の値(実体:zval構造体に収納)を、対応(reference or asign)させるさせることができるため、柔軟な変数運用をすることができる。

figure6
変数名($a)→シンボルテーブル→実際の値(実体:zval構造体に収納)
変数名($b)
変数名(・・・)


次回は、$a=$b;について説明したい。単純であるが、奥が深いcodeである。


PHP変数管理の目次はこちら 
  • 変数の代入は、値のコピーにあらず CPA-LABテクニカル spok
    前回の変数管理の基礎(PHPの参照とは何か) でシンボルテーブルについて説明した。これがわかっていないとPHPの変数管理はわからない。今回は、もっとも基本的な変数の値の代入、について説明する。code1$a=$bなぜ、こんな単純なことをいちいち説明しなけれ...

2008/01/26(土) はじめに-PHP変数管理解説(1)-参照と値渡しの明確な理解のために

PHPの参照はおかしいか?

「PHP5からオブジェクトは参照渡しに変更になった」というのはウソである。PHP4からPHP5への以降は、PHPで混乱している「参照」という用語を統一するせっかくのチャンスであったのに、PHPコミュニティ(又はZEND社)は重大な過ちを犯した。同じreference(s)という言葉を使っても、「シンボルテーブルを使った参照」と、(C言語のような)「ポインタを利用した参照」は、その原理も使い方も全く異なるのに、同じ「参照」という言葉を使ったがために、大きな混乱を呼んでいるように思う。

このカテゴリの記事について

この連載は、PHPの変数管理、特に参照代入と値渡し(コピー)代入の不十分な理解に基づく混乱を少しでも収束させるために書いた。実際は、自分自身がわからなくて、改めて調べ直したものである。言葉遣いは偉そうだが、これは簡潔に書くためであって、決して偉ぶっているわけでも、その道のプロであるわけでもない。

続きを読む

目次と今後の予定

  1. はじめに(この記事)
  2. PHPの変数管理(メモリ管理)の基礎
  3. 変数の代入は、値のコピーにあらず
  4. issetを正しく理解する。null値とunsetの違い-PHP変数管理
  5. PHPの配列管理方法を正しく理解する-ハッシュテーブルとZval
  6. PHPの配列上限数-PHP変数管理
(今後の予定)
一般の値の代入、配列の管理、オブジェクトの管理、グローバル変数の管理、スタティック変数の管理

続きを読む

# hashi 『PHPの何が嫌いって、変数管理がわかりずらいとこでした。この記事で大分すっきりしました。』 (2008/05/21 12:37)

2008/01/22(火) bake.phpでバリデーション(Validation)エラー

はてなブックマークの情報 はてなブックマークに登録 はてなブックマーク数 cakephpspok
bake.phpでバリデーション(Validation)を設定してみた。ら、エラーが。(cakephp1.2bata)
Warning (2): extract() [function.extract]: First argument should be an array [CORE\cake\libs\validation.php, line 791]
メールアドレスのフィールドだけをチェックするようにしたんだけど。。。
こういうのでエラーはつらいな。原因を特定する気力なし。betaだからしょうがないのか。

良いときは良いけど、はまるとつらい。cakephpの設計思想は好きなんだけどな。

cakephp1.2bata

(早速追記)
いちおう原因判明。こんなコードが生成されていた。
  • ●●_Controller.php内
	var $validate = array(
		'id' => array('_extract'),
		'mailaddress' => array('email'),
		'password' => array('_extract'),
		'name' => array('_extract'),
		'created' => array('_extract'),
		'modified' => array('_extract')
	);
よくあるタイプのuser管理のテーブルです。

'_extract'の設定が怪しいので、'_extract'はすべて消去して、mailaddressだけを残したら、エラーは消えました。そりゃ'_extract'ってアンダーバー'_'つきのメソッドだから、だめなんでないの?でも、詳しい原因究明をする気はないのでおいておきます。

2008/01/22(火) CakePHP,bake.phpはモデルから焼くべし

はてなブックマークの情報 はてなブックマークに登録 はてなブックマーク数 cakephpspok
cakephp 1.2beta

bake.phpで、一番簡単なものを作ろうと、まずはコントローラー(controller)から手をつけた。ほとんどのオプションを断っていったら、「そんなもんscaffoldで作れや!(意訳)」というメッセージが出て怒られた。いや、scaffoldを使わない一番簡単なものをみたかったんだけど。。。。

でも、モデル(Model)を先に作ってから、コントローラーを作ったら、さっきと同じ簡易オプションなのに怒られなかった。

初心者は簡単なコードを読みたいんだよ!ってことで、初めての人はとにかくMから作りましょう。

2008/01/22(火) cakephp1.2でbake

はてなブックマークの情報 はてなブックマークに登録 はてなブックマーク数 cakephpspok
cakephpをバージョン1.2にしてみた。

cakephpには、対話式に質問に答えていくと、自動でコードを出力してくれるbake.phpというプログラムがついてくる。

ので、やってみた。。。。(参考:CakePHP のおいしい食べ方 Easy Bake on Windows:Easy Bake on Windows)

起動の仕方は、cake\console\にcake.batというのがあるので、
  1. ウィンドウズのコマンドプロンプトで、appフォルダに移動
  2. >c:¥exaple¥example¥cakefoder¥cake¥console¥cake bake(¥は半角)

でOKでした(私の環境では。。。フルパスなので当然といえば当然。何か支障がでるのかしら。)。(v1.1とは手順が違う模様)。。。。で

英語だよおい。。。(当たり前)

仕組みがわかってないと質問の意味がわかんないよ。。。(当たり前)

ともかく、なんとか質問に答えて、やってみた。。。。ら

ちょっと感激。一通りできているじゃない。cakephpは抜群の評判でも、必ずしも評判のよろしくないbakeのようですが、私のような初学者が、学ぶにはたいへんグッドではないでしょうか。

管理人リンク

管理人の覚書&書き散らし

ブログでサイト制作覚書(Movableytpe4) http://www.cpa-lab.com/makebyblog/
CPA-LAB管理人専用(adiry) http://www.cpa-lab.com/shougakusei/2008/spok/


その他
SpoksLog http://www.spokslog.com/
CPA-Books http://www.cpa-lab.com/books/

2008/01/22(火) Zend Studioでのデバックトレース

はてなブックマークの情報 はてなブックマークに登録 はてなブックマーク数 php5spok
ステップ実行に感激したものの、ステップオーバー、ステップイントゥ、ステップアウトの意味がよくわからない。調べると以下のよう。

  • ステップイントゥ:とにかく1つずつ実行。他の関数が呼び出されたら、当然、そちらに移る。細かいが時間がかかる。
  • ステップアウト:その関数のreturnまで一気に実行して、呼び出しもとに戻る。ステップイントゥでスしょうもない関数にまで入り込んでしまったら、これを使うと元の関数に戻れる。
  • テップオーバー:1つづ実行するが、他の関数が呼び出された場合には、そちらには一気に実行する。つまり呼び出した関数のステップ実行はしない。

続きを読む

2008/01/22(火) ZendStudio5.5買ってみた

はてなブックマークの情報 はてなブックマークに登録 はてなブックマーク数 php5spok
奮発してあこがれの統合環境、ZendStudio5.5を買った。
しかし、ZendPlatformがインストールできない。問い合わせたところ、
Zend Platform 2.2.2がphp 5.2.x系に対応してい
ないことが原因と考えられます。
だと。(当方の環境はphp5.2.3)
リモートデバッグができるというから買ったのに。。。。。はい、事前に調べない私が悪いです。

同じメールで
Zend Platformではなく、Zend Debuggerをインストールしていただくと
いう方法がございます。 
ということなので、Zend Debuggerを入れてみた。。。。。ら

ZendDebuggerすごいよ。ステップ実行に感激。これで十分です。

しかし、エディタがしょぼい。秀丸に使い慣れているとすこぶるよろしくない。
しばらくコーディングは、今までとおり、まめFile5+秀丸でいっておきましょう。会計士は保守的なのだ。

2008/01/17(木) cakephpで使えるSQLiteのバージョン

はてなブックマークの情報 はてなブックマークに登録 はてなブックマーク数 cakephpspok
私の環境でテストするとcakephpでは、 sqlite2.8.17 でした。できればversion 3を使いたいのだけれど。。。
ソースをちょい見すると、全部SQL文を書き出しているよう。すごいね。pdoを使わないと、SQLite3は使えないから、こりゃしばらくSQLite2でがんばるしかない。

どうせならMySQL使ってみましょうか。定番らしいが私はほとんど触ったことない。

2008/01/17(木) CakePHPとSQLite(&MySQL)

はてなブックマークの情報 はてなブックマークに登録 はてなブックマーク数 cakephpspok
(追記)この記事には続きがあります。cakephpとSQLiteの続き(2008/2/2)
(追記の追記)もっと効率的な修正方法があります。CakePHP1.2bとSQLite不具合のもっと簡単な直し方
(追記の追記の追記)CakePHP1.2をSQLite3で動かしてみた。&ダウンロード

なぜかサンプル程度つまづく。CakeでSQLiteを使っているのは少数派なのか、情報が少ない。

データベースのidフィールドが integer primary key なのに、cakephpで作られるSQL文が '' の入力になってたものだから、 datatype errorがでて困っていた。SQLiteはデータ型はルーズだけど、こんなエラーはだすのだなっと。

英語圏でも困っている人がいるようだが、Englishなのは私はダメなのである。http://groups.google.co.jp/group/cake-php/browse_thread/thread/d0160763dece38b0/6b9b7246a72945e2?lnk=gst&q=datatype+mismatch#6b9b7246a72945e2

こんな感じ
Warning: sqlite_query() [function.sqlite-query]: datatype mismatch in C:\www\Cake\cake\libs\model\dbo\dbo_sqlite.php on line 115

Query: INSERT INTO "dbs" ("id","name") VALUES ('','abc') 
Warning: SQL Error: 20: datatype mismatch in C:\www\Cake\cake\libs\model\datasources\dbo_source.php on line 440

で、ソースをよくみると。。。原因はわかったが、どこを直すべきか難しい。とりあえずこうした。
/cake/libs/dbo/dbo_sqlite.php
	function value ($data, $column = null, $safe = false) {
		$parent = parent::value($data, $column, $safe);

		if ($parent != null) {
			return $parent;
		}

		if ($data === null) {
			return 'NULL';
		}

		if ($data === '') {
			return  "''";
		}
を探しだし
		if ($data === null) {
			return 'NULL';
		}

		if ($data === null || $data === '' && $column=='integer') {
			return 'NULL';
		}
に変更。

cakephp1.19でのお話 うーん、1.2にしようかな。

(追記)

実はMySQLでも同じ現象が発生した。...もう一度よく考えると、

cake/libs/mode/dbo/dbo_mysql.phpの
    • function value($data, $column = null, $safe = false)
if ($data === '') {
  return  "''";
}

if ($data === '') {
//spok_added
    if($column=='integer'){return 'null';}
//spok_end
    return  "''";
}
とすればうまくいった。
おそらくsqliteも、最初の修正をしなくても、dbo_sqlite.phpの同じ箇所を直せばこれで通るでしょう。

しかし、こういうのみんなクリアーしてるのかね。
全然cakephp楽じゃないよ。これだけでえらい時間食ったよ。

こちらも参考になりました。http://papuh.s3.zmx.jp/2008/01/15/cakephp%E3%81%AE%E3%83%90%E3%83%BC%E3%82%B8%E3%83%A7%E3%83%B3%E3%82%A2%E3%83%83%E3%83%97%E3%80%801206311-beta/

MySQL5.0.45 でのお話
  • [PHP]CakePHPをAN HTTPD+SQLiteで動かす genms’ blog
    この環境で、CakePHPのScaffoldingを一通り動作させることができました。 ただその際、環境特有と思われる設定や変更が発生したので、メモ。 環境 AN HTTPD 1.42n PHP 5.1.4 SQLite 2 【AN HTTPD関係】 m...
  • Cakephpでsqliteの続き。editとdeleteの修正 CPA-LABテクニカル spok
    以前にSQliteでのnew時(insert)の不具合を修正したのだけれど、今度は、editとdeleteでも不具合があることがわかった。しばらくMySQLのお勉強をしていたので、sqliteはほっておいたんだけど、やっぱりsqliteが恋しいので戻ってき...
  • CakePHP1.2bとSQLite不具合のもっと簡単な直し方 CPA-LABテクニカル spok
    私、nightlyって知りませんでした。ソフト開発の世界では、nightly buildとは、開発途上版ということなのですね。で、CakePHPでは、そのnightly buildが公開されていると。だからそれを使えばいいだぞ、と。こちらCakePHPでは...

2008/01/17(木) 2008-01-17

はてなブックマークの情報 はてなブックマークに登録 はてなブックマーク数 cakephpspok
CakePHPではまったこと 4(sqliteをデータベースとして使う) http://red-treasure.com/report/?p=45

cakephpリンク集

はてなブックマークの情報 はてなブックマークに登録 はてなブックマーク数 cakephpspok
本家 http://cakephp.org/
UserForrumJapan http://cakephp.jp/modules/newbb/
CakePHP プログラマーズ リファレンスガイド http://cakephp.jp/doc/
便利 http://cakephp.jp/modules/newbb/viewtopic.php?topic_id=334&forum=3&post_id=573#forumpost573
CakePHP guide http://www.blueocean.bz/blog/cakephp/index.php
CakePHPフレームワークによる快速WEB開発 http://codezine.jp/a/article/aid/670.aspx?p=1
クロアチアで働くプログラマー日記 http://yasue.us/cakephp/


CakePHP Security コンポーネントのまとめ  http://www.syuhari.jp/blog/archives/148
CakePHP Ajax のフォームを作成する http://www.syuhari.jp/blog/archives/186
CakePHPで自動ログインコンポーネント  http://code.nanigac.com/source/view/323
http://cakephp-saboten.blogspot.com/


PHPではてなパーサー http://d.hatena.ne.jp/anatoo/20080102/1199241367

CakePHP1.2 Form ヘルパーで日付のフォームを作る http://www.syuhari.jp/blog/archives/192

2008/01/11(金) php5。さくらインターネット。pear Mail_Mime

はてなブックマークの情報 はてなブックマークに登録 はてなブックマーク数 php5spok
pearでMail_Mineをインストールしようとすると、
%pear install mail_mime
pear/Mail_Mime requires PEAR Installer (version >= 1.6.0), installed version is 1.4.11
pear/Mail_mimeDecode requires PEAR Installer (version >= 1.6.0), installed version is 1.4.11
pear/Mail_mimeDecode requires package "pear/Mail_Mime" (version >= 1.4.0, excluded versions: 1.4.0)
No valid packages found
install failed
なるエラーが。

調べると、pearのバージョンは1.6.2になっているし問題ない(←実はここが落とし穴。1.6.2はインストールされていても。動いているpearがさくらインターネットの古いpear&php4だったりする。)。ちまたでは
pear upgrade pear
なる民間療法が検索されるが、当然、効き目なし。

さらに調べると、ああ、pathが通っていないからphp4が動いていることが原因のよう。
だってpear -Vで調べるとわかる。

http://www.pear-forum.org/viewtopic.php?p=2366

pear config-set php_bin /home/example/php5/bin/php 
西洋ナシ構成-セットphp_bin/home/example/php5/bin/php 

export PHP_PEAR_PHP_BIN=/home/example/php5/bin/php 
輸出PHP_PEAR_PHP_BIN=/home/example/php5/bin/php 

export PATH=/home/example/pear/:/home/example/php5/bin:$PATH 
輸出PATH=/home/example/pear/:/家/ユーザー名/php5/ごみ箱:$PATH 
を参考に
pear config-set php_bin /home/example/bin/php5
setenv PHP_PEAR_PHP_BIN /home/example/bin/php5
setenv PATH /home/example/share/pear5/:/home/example/bin
とすると無事成功。
コマンドラインでもphp5が優先で動くようになる。

これもメモしとく
What does "pear -V" show you? 
「西洋ナシ-V」は、あなたに何を示しますか? 

I'm not sure, but maybe "pear clear-cache" might help.
私にはわかりません、しかし、多分、「西洋ナシ見通しがきくキャッシュ」は助けるかもしれないでしょう。

2008/01/11(金) pearの初期設定。php5 さくらインターネット

http://phptips.seesaa.net/archives/200703-1.htmlが詳しい。

まずは
pear -vでベースを把握し、pear helpで勉強して
.pearrcをユーザールートに作る。

pear config-set bin_dir /home/example/pear/bin
pear config-set doc_dir /home/example/pear/PEAR/docs
pear config-set ext_dir /home/example/pear/PEAR/extensions
pear config-set php_dir /home/example/pear/PEAR
pear config-set cache_dir /home/example/pear/PEAR/cache
pear config-set data_dir /home/example/pear/PEAR/data
pear config-set php_bin /home/example/bin/php5
pear config-set test_dir /home/example/pear/PEAR/tests
pear config-set download_dir /home/example/pear/temp/download
pear config-set temp_dir /home/example/pear/temp
http://pear.php.net/manual/ja/installation.cli.php

も参照

2008/01/10(木) .htaccessでurl偽装時の注意点。さくらインターネット

さくらインターネット&マルチドメインでの運用上の注意

RewriteBaseが必ず必要
cpa-lab/test/test2/に.htaccessを置く場合。
RewriteEngine on
RewriteBase /test/example
RewriteCond	%{REQUEST_FILENAME}	!-f
RewriteCond	%{REQUEST_FILENAME}	!-d
RewriteRule ^(.*)$ index.php?param=$1  [L]
となる

http://pakapaka.jp/softwareinfo/71.html

本来、RewriteBaseは必須のよう。