Symfony 3.0: ロードマップ

(訳者)この記事は、SymfonyプロジェクトマネージャのFabien Potencierの記事を、訳者が日本語訳したものです。訳間違え、事実誤認などが含まれるかもしれませんがご容赦ください。

          • -


昨年の間、私はSymfony3.0について多くの会議で話してきました。私はSymfony3.0の最適な戦略について長い間考えてきました。今が私の考えを皆様と共有するときです。


メジャーバージョン

開発者の何人かや、多くのプロジェクトマネージャーは、彼らのお気に入りのオープンソースライブラリのメジャーバージョンが発表されることを心配しています。おそらくそれは、メジャーバージョンが後方非互換な変更を想像させるからでしょう。多くの疑問が起こります:変更は重大な価値を私のプロジェクトにもたらすのか? ロードマップがアップグレードを見込むに十分明確だろうか? アップグレードするのは簡単/可能性がある? もし私がアップグレードを望まなかったり不可能だったりしたらどうなるだろうか? などなど。


新しいメジャーバージョンへの恐れというのは過去の悪い経験に基づいているものです:Perl 6やPHP 6を思い出してみてください。Symfonyにおいても、Symfony 2は大きな進化であり、symfony 1との違いはかなり大きなものでした。Symfony 3について話すことは、人々をやきもきさせるということに、私は気が付きましたので、この投稿はSymfony 3の戦略と、みなさんがパニックにならなくてもいい理由について説明します。


第一に、メジャーバージョンが定期的に必要だということを皆さんは知っていると思います。もう使われていない機能を取り除いたり、アーキテクチャ上の間違えを修正したり、PHPの新しい能力や、ベストプラクティスの移り変わり、新しいWebパラダイムといったエコシステムを考慮したりするために、後方互換性を壊す必要があります。インターネットはとても速いペースで発展しており、もしわれわれがSymfonyを早く対応させることができなければ、あなたが想像することができるより早く、Symfonyは意味のない物になってしまいます。


Symfonyのプロジェクトマネージャーとして、私の責任はコードをできるだけ安定に保つことです。しかし安定性は現状維持ということを意味しません。というのも我々は、あなた自身で確かめることができますが、Symfony 2.4や2.5や2.6において、新しい機能を追加したり、アーキテクチャの間違いを修正したりしました。それらすべてのバージョンは新しい機能を搭載していますし、それぞれがフレームワークにとって大きな一歩となっています。しかしながら、後方互換性が保たれたため、アップグレードはかなり簡単です。使われていないもしくは非推奨された機能のための後方互換性レイヤーは挑戦です。(パフォーマンス低下を最小にする必要があるということについては触れていません。)Symfony2は、分離されたコンポーネントによって作られたかなり強固な基盤上に基づいていますからそれはかなり簡単でした。セマンティックバージョニングの定義によって、メジャーバージョンはまさに、事態を収拾したり、粗雑なつくりを取り除くマイルストーンとなります。


Symfony3.0とは何?

いつもマイナーバージョンで新しい機能が追加され、あるいは機能が削除されたりするため、本日、あなたのコードを3.0により準拠するようにことができます。Symfony 3.0アップグレードガイドを読んで、提案された個々の変更を見てください。これにより、あなたのペースで十分な時間をもってマイグレーションの計画を立てることができます。


おそらくあなたが今ご想像した通り、Symfony 3.0は大改革とはならない予定で、フレームワークの低レベルアーキテクチャは変更されません。ここに、我々がSymfony3をよりよくするために、Symfony2.xにおいて行った変更を示します。

  • Symfony 3.0はよりスタンダードになります(ロギングにおいてPSR-3の使用、Symfony\Component\HttpKernel\Log\LoggerInterface インターフェースの削除、など)
  • Symfony 3.0はアーキテクチャ上の間違えをいくつか修正します。(ステートフルコンソールヘルパーはよりよい代替えを好んで取り除かれます(ProgressBar 対 ProgressHelper、Table 対 TableHelper、Yaml::parse()はもはやファイル名をサポートしなくなります)
  • Symfony 3.0はこれまでと比べて、より分離され、より再利用可能になります。(HttpKernelはいくつかの小さいクラスに分離される予定です。インスタンスプロファイラーはスタンドアローンとなります。クラスはバンドルからコンポーネントに移動されます。コンポーネントは現在の物から抽出されます。)
Symfony 3.0スケジュール

新しいメジャーバージョンについての劇的な事件を避けることも、早期かつ頻繁なコミュニケーションによって可能になります。だから、Symfonyコミュニティは我々の戦略を資料にする作業に没頭しています。これは後方互換性に関する約束事からバージョンロードマップ、LTSリリースにわたります。


新しいバージョンの衝撃を最小化する一つの方法は、それらを予測可能にすることです。我々のロードマップによれば、Symfony2.7は次の長期サポートリリースとして、2015年5月にリリースされます。そして2.7は2018年5月までバグ修正が行われ、2019年5月までセキュリティ修正が行われます。2.8の予定の代わりとして、2.7の後に一気に3.0までバージョンを上げるよう私は提案します。つまり、Symfony 3.0は2015年11月にリリースされ、3.x系の最初の長期サポートリリースは3.3となり、これは2017年の3月にリリースされます。


相互に作用するSymfonyロードマップはSymfony 3.x ブランチを考慮してアップデートされています。


あなたは何をすればいいか? リリースプロセスドキュメントの章で説明された通り、2つのアップグレード戦略があります。

"二重メンテナンスモードはすべてのSymfonyユーザーを幸せにするために採用されました。最新の最高のバージョンを使いたい、高速移住者はstandardバージョンを使ってください。これは新しいバージョンが6か月ごとに発行され、2か月のアップグレード期間があります。より安定したものを使いたい会社はLTSバージョンを使ってください。これは新しいバージョンが2年ごとに発行され、1年のアップグレード期間があります。"

Symfony 3.0はどこにあるの?

誰でもSymfony 3.0に貢献しやすいようにするため、メインリポジトリは、今現在、Symfony 3.0のコードをホストしています。来るべき2.6と2.7バージョンへのブランチもすでに作成されています。


もしあなたのプロジェクトが最新の2.xの進化を追いかけようとSymfony masterブランチを使っているのであれば、本日、2.7ブランチへの切り替えを考えるべきです。マージ戦略は現在と同じになる予定ですが、非常に小さい変更を伴います。

  • 後方互換性を壊さない、もしくは現状のコードに影響を与えない新しい機能は2.7にマージされます。
  • 2.7ブランチで動かす方法がない新しい機能は3.0にのみマージされます。
  • バグ修正はやはり一番大きいバージョンと、まだメンテナンスされているブランチの両方にマージされ、masterブランチ(すなわち3.0)を含む最新のバージョンへ定期的にマージされます。
Symfony 3.0 最低のPHPバージョン

少なくとも最後ではない、Symfony 3.0用のPHPの最少バージョンは何でしょう? 私が数日前に開始した質問。その結果を以下に挙げます。

Version Votes %
5.3.3 31 2%
5.3.x 56 3%
5.4.x 260 16%
5.5.x 568 35%
5.6.x 495 30%
7.x 225 14%

これらの結果に基づいて、私はSymfony 3.0について必要とするPHPの最低バージョンをPHP 5.5と提案します。来年のいつかにおいて、我々のニーズと、ホスティング会社やLinuxディストリビューションによって使われるもっとも人気のPHPバージョンがなんであるかという理由によって、私はこれをPHP5.6に上げることを保留したいと思います。


どうやってあなたは役立てますか?

今日、Symfony 3.0のために行われるべき、簡単な変更がたくさんあります。第一に、2.7ブランチにおいて、すべての非推奨の機能が非推奨ログを出力することを求めています。(これは我々が2.3リリース時に行ったことと似ています) そして、非推奨のすべてがmasterブランチにおいて取り除かれなければなりません。最後に、アップグレードガイドはテスト済みであり、アップグレードプロセスが誰にとってもできるだけ簡単になるように拡張されるべきです。具体的には、Github上の3.0としてタグ付けされた問題を見てください。



Happy Coding!

          • -

(訳者)訳に間違え等ありましたら、コメントでお知らせください。

この記事は以下のURLの日本語訳です。
http://symfony.com/blog/symfony-3-0-the-roadmap

2014/11/12 1:38

Fedora19にMySQL-5.6.14-1をインストールする

rpmから入れます。
OracleのサイトからURLをゲットしてください。
http://dev.mysql.com/downloads/mysql/#downloads



↓このrpm固めたやつをゲットしてください。
Red Hat/Oracle Enterprise Linux ver. 6 (x86, 64-bit), RPM Bundle


Downloadボタンをしたら登録するかID入れろって言われますが、
下のほうにある「No thanks, just start my download.」を選ぶと華麗にスルーを決められます。


落としたら、必要なパッケージ入れます。

[root@db1 ~]# yum install libaio libaio-devel
[root@db1 ~]# yum install perl-Data-Dumper
これを入れないとrpmインストール中に以下のようなエラーが出る。

Can't locate Data/Dumper.pm in @INC (@INC contains: /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .) at /usr/bin/mysql_install_db line 42.


あとはrpmをインストールするだけ。

[root@db1 ~]# wget http://cdn.mysql.com/Downloads/MySQL-5.6/MySQL-5.6.14-1.el6.x86_64.rpm-bundle.tar
[root@db1 ~]# cp MySQL-5.6.14-1.el6.x86_64.rpm-bundle.tar /usr/local/src/




[root@db1 ~]# cd /usr/local/src/
[root@db1 src]# ls -la
合計 214880
drwxr-xr-x.  2 root root      4096 10月 22 20:03 .
drwxr-xr-x. 12 root root      4096 10月 21 21:09 ..
-rw-r--r--   1 root root 220026880 10月 22 20:03 MySQL-5.6.14-1.el6.x86_64.rpm-bundle.tar

[root@db1 src]# tar xvf MySQL-5.6.14-1.el6.x86_64.rpm-bundle.tar
[root@db1 src]# ls -la
合計 429756
drwxr-xr-x.  2 root root       4096 10月 22 20:03 .
drwxr-xr-x. 12 root root       4096 10月 21 21:09 ..
-rw-r--r--   1 root root  220026880 10月 22 20:03 MySQL-5.6.14-1.el6.x86_64.rpm-bundle.tar
-rw-r--r--   1 7155 wheel  18534880  9月 11 12:24 MySQL-client-5.6.14-1.el6.x86_64.rpm
-rw-r--r--   1 7155 wheel   3329604  9月 11 12:24 MySQL-devel-5.6.14-1.el6.x86_64.rpm
-rw-r--r--   1 7155 wheel  85034772  9月 11 12:24 MySQL-embedded-5.6.14-1.el6.x86_64.rpm
-rw-r--r--   1 7155 wheel  57625168  9月 11 12:25 MySQL-server-5.6.14-1.el6.x86_64.rpm
-rw-r--r--   1 7155 wheel   1936928  9月 11 12:26 MySQL-shared-5.6.14-1.el6.x86_64.rpm
-rw-r--r--   1 7155 wheel   3969816  9月 11 12:26 MySQL-shared-compat-5.6.14-1.el6.x86_64.rpm
-rw-r--r--   1 7155 wheel  49586908  9月 11 12:26 MySQL-test-5.6.14-1.el6.x86_64.rpm




[root@db1 src]# yum install MySQL-*.rpm
MySQL-client-5.6.14-1.el6.x86_64.rpm を調べています: MySQL-client-5.6.14-1.el6.x86_64
MySQL-client-5.6.14-1.el6.x86_64.rpm をインストール済みとして設定しています
MySQL-devel-5.6.14-1.el6.x86_64.rpm を調べています: MySQL-devel-5.6.14-1.el6.x86_64
MySQL-devel-5.6.14-1.el6.x86_64.rpm をインストール済みとして設定しています
MySQL-embedded-5.6.14-1.el6.x86_64.rpm を調べています: MySQL-embedded-5.6.14-1.el6.x86_64
MySQL-embedded-5.6.14-1.el6.x86_64.rpm をインストール済みとして設定しています
MySQL-server-5.6.14-1.el6.x86_64.rpm を調べています: MySQL-server-5.6.14-1.el6.x86_64
MySQL-server-5.6.14-1.el6.x86_64.rpm をインストール済みとして設定しています
MySQL-shared-5.6.14-1.el6.x86_64.rpm を調べています: MySQL-shared-5.6.14-1.el6.x86_64
MySQL-shared-5.6.14-1.el6.x86_64.rpm をインストール済みとして設定しています
MySQL-shared-compat-5.6.14-1.el6.x86_64.rpm を調べています: MySQL-shared-compat-5.6.14-1.el6.x86_64
MySQL-shared-compat-5.6.14-1.el6.x86_64.rpm をインストール済みとして設定しています
MySQL-test-5.6.14-1.el6.x86_64.rpm を調べています: MySQL-test-5.6.14-1.el6.x86_64
MySQL-test-5.6.14-1.el6.x86_64.rpm をインストール済みとして設定しています
依存性の解決をしています
--> トランザクションの確認を実行しています。
---> パッケージ MySQL-client.x86_64 0:5.6.14-1.el6 を インストール
---> パッケージ MySQL-devel.x86_64 0:5.6.14-1.el6 を インストール
---> パッケージ MySQL-embedded.x86_64 0:5.6.14-1.el6 を インストール
---> パッケージ MySQL-server.x86_64 0:5.6.14-1.el6 を インストール
---> パッケージ MySQL-shared.x86_64 0:5.6.14-1.el6 を インストール
---> パッケージ MySQL-shared-compat.x86_64 0:5.6.14-1.el6 を インストール
---> パッケージ MySQL-test.x86_64 0:5.6.14-1.el6 を インストール
--> 依存性解決を終了しました。

依存性を解決しました

======================================================================================================================================================================================
 Package                                    アーキテクチャー              バージョン                            リポジトリー                                                     容量
======================================================================================================================================================================================
インストール中:
 MySQL-client                               x86_64                        5.6.14-1.el6                          /MySQL-client-5.6.14-1.el6.x86_64                                81 M
 MySQL-devel                                x86_64                        5.6.14-1.el6                          /MySQL-devel-5.6.14-1.el6.x86_64                                 19 M
 MySQL-embedded                             x86_64                        5.6.14-1.el6                          /MySQL-embedded-5.6.14-1.el6.x86_64                             432 M
 MySQL-server                               x86_64                        5.6.14-1.el6                          /MySQL-server-5.6.14-1.el6.x86_64                               235 M
 MySQL-shared                               x86_64                        5.6.14-1.el6                          /MySQL-shared-5.6.14-1.el6.x86_64                               8.4 M
 MySQL-shared-compat                        x86_64                        5.6.14-1.el6                          /MySQL-shared-compat-5.6.14-1.el6.x86_64                         11 M
 MySQL-test                                 x86_64                        5.6.14-1.el6                          /MySQL-test-5.6.14-1.el6.x86_64                                 318 M

トランザクションの要約
======================================================================================================================================================================================
インストール  7 パッケージ

合計容量: 1.1 G
インストール容量: 1.1 G
Is this ok [y/d/N]: y
Downloading packages:
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
警告: RPMDB は yum 以外で変更されました。
  インストール中          : MySQL-devel-5.6.14-1.el6.x86_64                                                                                                                       1/7
  インストール中          : MySQL-client-5.6.14-1.el6.x86_64                                                                                                                      2/7
  インストール中          : MySQL-test-5.6.14-1.el6.x86_64                                                                                                                        3/7
  インストール中          : MySQL-embedded-5.6.14-1.el6.x86_64                                                                                                                    4/7
  インストール中          : MySQL-shared-compat-5.6.14-1.el6.x86_64                                                                                                               5/7
  インストール中          : MySQL-shared-5.6.14-1.el6.x86_64                                                                                                                      6/7
  インストール中          : MySQL-server-5.6.14-1.el6.x86_64                                                                                                                      7/7
  検証中                  : MySQL-server-5.6.14-1.el6.x86_64                                                                                                                      1/7
  検証中                  : MySQL-embedded-5.6.14-1.el6.x86_64                                                                                                                    2/7
  検証中                  : MySQL-shared-5.6.14-1.el6.x86_64                                                                                                                      3/7
  検証中                  : MySQL-client-5.6.14-1.el6.x86_64                                                                                                                      4/7
  検証中                  : MySQL-shared-compat-5.6.14-1.el6.x86_64                                                                                                               5/7
  検証中                  : MySQL-test-5.6.14-1.el6.x86_64                                                                                                                        6/7
  検証中                  : MySQL-devel-5.6.14-1.el6.x86_64                                                                                                                       7/7

インストール:
  MySQL-client.x86_64 0:5.6.14-1.el6         MySQL-devel.x86_64 0:5.6.14-1.el6                 MySQL-embedded.x86_64 0:5.6.14-1.el6         MySQL-server.x86_64 0:5.6.14-1.el6
  MySQL-shared.x86_64 0:5.6.14-1.el6         MySQL-shared-compat.x86_64 0:5.6.14-1.el6         MySQL-test.x86_64 0:5.6.14-1.el6


MySQLの初期設定と起動

[root@db1 ~]# mysql_install_db --user=mysql --ldata=/var/lib/mysql/

[root@db1 ~]# /etc/init.d/mysql start
Starting MySQL. SUCCESS!


[root@db1 ~]# mysql -uroot
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.6.14 MySQL Community Server (GPL)

Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> SET PASSWORD FOR root@localhost=PASSWORD('admin');
Query OK, 0 rows affected (0.00 sec)

mysql> exit

[root@db1 ~]# mysql_secure_installation
[root@db1 ~]# systemctl enable mysql.service

PHP関西勉強会@JAWS FESTA Kansai 2013

blog を書くまでが勉強会
というわけで、JAWS FESTA Kansai 2013のPHP関西勉強会に行ってきました。

セッション1

PHPエンジニア養成読本買います。
クラウドの説明とか。

セッション2

ComposerはSilexで使ってます。

セッション3

PhpStorm(IDE)が良さげ?
BEAR.Sunday(PHP5.4以降のフレームワーク)先取り!
PSR
Vagrant



今回心に残った一文はこちら
セッション1をしてくださった@omoonさんの
「今後5年、phpで活動する場合、クラウドサービスを全く知らないで活動するのは難しくなっていくだろう。」(意訳)

phpを他のLLに替えても同じことがいえそう。
javaとかC#とかエンタープライズ寄りの人は・・・



以上、非常に刺激的でした。

PHPの代入と参照の違い2

昨日の件、ブコメなどを読んでるとちょっと私の書き方悪かったみたいなので、
PHP.netの内容を引用しつつもう少し解説してみる。
メモ書きなので、元記事にはリンクしない。

php.netによる定義抜粋

リファレンスとは?
http://www.php.net/manual/ja/language.references.whatare.php

PHP において、リファレンスとは同じ変数の内容を異なった名前で コールすることを意味します。これは C のポインタとは異なります。 


http://php.net/manual/ja/language.references.whatdo.php

<?php
$a =& $b;

(略)

ここで、$a と $b は完全に同じで、$a が $b を 指しているわけではなく、その逆でもありません。$a と $b は同じ場所を指しているのです。 

ここまで定義の話。OKね?




元記事への突込み

んで、リンク元の人はこれがわからん!って言ってるんでしょ?

<?php
/* スカラー変数への代入 */
$a = 1;
$b =& $a;
$c = $b;
$c = 7; // $c はリファレンスではないので $a や $b の値は変わりません
$c = $b;

ってやると、$b はリファレンスだから、$c もリファレンスになって、$c は $bと $a と同じ場所指すんじゃないん?ってことでしょ。


違う。

それがやりたいんだったら

$c =& $b;

って書かなきゃいけません。

$c = $b;

これは単なる値の代入だから、$c には( $b がリファレンスであろうとなかろうと)$b の値が代入されるし、$c は $b と同じ場所を指さない。


違いはここだけ。

$c = $b;  // $c には $b の値が代入
$c =& $b; // $c は $b と同じ場所を指す(これを「 $c は $b の別名」という言い方をするのが個人的には好きです)

あと、配列について補足。

http://php.net/manual/ja/language.references.whatdo.php

配列内のリファレンスの挙動はその要素ごとに決まるということです。 個々の要素のリファレンスに関する動きは、 配列コンテナがリファレンスであるかどうかとは独立しています。 

詳しくスクリプトで流れを追いたい場合はこちら

p1.php

<?php

//参照でくっつけた a,bは同じデータを指す。一心同体。
$a = 1;
$b =& $a;
xdebug_debug_zval( 'a' );
xdebug_debug_zval( 'b' );
echo PHP_EOL;

// $c に $b を単に代入しても、 $b と $c は違うデータを指すよ。
$c = $b;
$c = 111;
xdebug_debug_zval( 'a' );
xdebug_debug_zval( 'b' );
xdebug_debug_zval( 'c' );
echo PHP_EOL;

// $c が $b と同じデータを指したければ参照代入演算子(=&)を使う必要があるよ。
$c =& $b;
$c = 222;
xdebug_debug_zval( 'a' );
xdebug_debug_zval( 'b' );
xdebug_debug_zval( 'c' );
echo PHP_EOL;

実行結果

C:\Users\bravewood\Desktop>php p1.php
a: (refcount=2, is_ref=1)=1
b: (refcount=2, is_ref=1)=1

a: (refcount=2, is_ref=1)=1
b: (refcount=2, is_ref=1)=1
c: (refcount=1, is_ref=0)=111

a: (refcount=3, is_ref=1)=222
b: (refcount=3, is_ref=1)=222
c: (refcount=3, is_ref=1)=222

p2.php

<?php

$a = 1;
$b =& $a;
$c =& $b;

xdebug_debug_zval( 'a' );
xdebug_debug_zval( 'b' );
xdebug_debug_zval( 'c' );
echo PHP_EOL;

//参照でくっつけた $a $b $c はどれに何を代入してもすべて同じデータを示す。一心同体。
$a = 111;
xdebug_debug_zval( 'a' );
xdebug_debug_zval( 'b' );
xdebug_debug_zval( 'c' );
echo PHP_EOL;

$b = 222;
xdebug_debug_zval( 'a' );
xdebug_debug_zval( 'b' );
xdebug_debug_zval( 'c' );
echo PHP_EOL;

$c = 333;
xdebug_debug_zval( 'a' );
xdebug_debug_zval( 'b' );
xdebug_debug_zval( 'c' );
echo PHP_EOL;

実行結果

C:\Users\bravewood\Desktop>php p2.php
a: (refcount=3, is_ref=1)=1
b: (refcount=3, is_ref=1)=1
c: (refcount=3, is_ref=1)=1

a: (refcount=3, is_ref=1)=111
b: (refcount=3, is_ref=1)=111
c: (refcount=3, is_ref=1)=111

a: (refcount=3, is_ref=1)=222
b: (refcount=3, is_ref=1)=222
c: (refcount=3, is_ref=1)=222

a: (refcount=3, is_ref=1)=333
b: (refcount=3, is_ref=1)=333
c: (refcount=3, is_ref=1)=333


p3.php

<?php

$a = 1;
$b =& $a;
$c =& $b;

xdebug_debug_zval( 'a' );
xdebug_debug_zval( 'b' );
xdebug_debug_zval( 'c' );
echo PHP_EOL;

//参照でくっつけた $a $b $c はどれに何を代入してもすべて同じデータを示す。一心同体。
//でも一つだけ一心同体から引きはがす方法がある。それは、別の参照を代入することだよ。

$d = 4;
$c =& $d; //別の参照を代入
xdebug_debug_zval( 'a' );
xdebug_debug_zval( 'b' );
xdebug_debug_zval( 'c' );
xdebug_debug_zval( 'd' );
var_dump( $a );
var_dump( $b );
var_dump( $c );
var_dump( $d );
echo PHP_EOL;

実行結果

C:\Users\bravewood\Desktop>php p3.php
a: (refcount=3, is_ref=1)=1
b: (refcount=3, is_ref=1)=1
c: (refcount=3, is_ref=1)=1

a: (refcount=2, is_ref=1)=1
b: (refcount=2, is_ref=1)=1
c: (refcount=2, is_ref=1)=4
d: (refcount=2, is_ref=1)=4
int(1)
int(1)
int(4)
int(4)

p4.php
(オブジェクトだけちょっと特殊)

<?php

$a = new stdClass;
$b = $a;
xdebug_debug_zval( 'a' );
xdebug_debug_zval( 'b' );
echo PHP_EOL;

//オブジェクトの場合、実はデータコンテナにはオブジェクトそのものではなくオブジェクトIDなるものが入っているんだよ。
var_dump( $a );
var_dump( $b );
echo PHP_EOL;

//オブジェクトIDを通してオブジェクトを操作したら、そのオブジェクトを指しているすべての変数に影響するよ
$a->hoge = 111;
xdebug_debug_zval( 'a' );
xdebug_debug_zval( 'b' );
echo PHP_EOL;

//でも $b と $a は参照でつながれたわけじゃないから $b に何か別の値を入れたら、 $a とは縁が切れるよ。
$b = 222;
xdebug_debug_zval( 'a' );
xdebug_debug_zval( 'b' );
echo PHP_EOL;

//参照代入演算子で結び付けると、オブジェクト以外の時と同じ動作になるよ
$b =& $a;
$a->hoge = 333;
xdebug_debug_zval( 'a' );
xdebug_debug_zval( 'b' );
echo PHP_EOL;

実行結果

C:\Users\bravewood\Desktop>php p4.php
a: (refcount=2, is_ref=0)=class stdClass {  }
b: (refcount=2, is_ref=0)=class stdClass {  }

class stdClass#1 (0) {
}
class stdClass#1 (0) {
}

a: (refcount=2, is_ref=0)=class stdClass { public $hoge = (refcount=1, is_ref=0)=111 }
b: (refcount=2, is_ref=0)=class stdClass { public $hoge = (refcount=1, is_ref=0)=111 }

a: (refcount=1, is_ref=0)=class stdClass { public $hoge = (refcount=1, is_ref=0)=111 }
b: (refcount=1, is_ref=0)=222

a: (refcount=2, is_ref=1)=class stdClass { public $hoge = (refcount=1, is_ref=0)=333 }
b: (refcount=2, is_ref=1)=class stdClass { public $hoge = (refcount=1, is_ref=0)=333 }

ここまで書けばOKでしょ。
さて、パズドラやるか。

PHPは代入と参照の違い

http://ameblo.jp/nikko-inma/entry-11122429825.html
http://b.hatena.ne.jp/entry/ameblo.jp/nikko-inma/entry-11122429825.html

ふむふむ、なになに、PHPはクソ言語で、C++VBもクソで、

きっちり書きたいときはC
きっちり書きたいときはC
きっちり書きたいときはC

イスから転げ落ちるわ!!!


ちょっとこれはPHPerとしては突っ込まざるを得ない。
いつ突っ込むかって?

今でしょ!


とりあえず上記サイトで書かれてるサンプルじゃあ代入と参照が深く理解できないだろうってこともあり、その部分補足してみよう。


まずサンプルプログラム

<?php
    

$a = 1;
xdebug_debug_zval( 'a' );


$b = $a; //これはただの値の代入(ただしこので時点でbの変数コンテナは出来ない(copy on write))
xdebug_debug_zval( 'a' );
xdebug_debug_zval( 'b' );

$b = 111; //bの値を変えるとaの参照カウント(refcount)が1減って、新しくbの変数コンテナが作られる。
xdebug_debug_zval( 'a' );
xdebug_debug_zval( 'b' );


echo "----------------ここまで代入のみ、ここから参照(&)使うよ----------------\n";


$x = 1;
xdebug_debug_zval( 'x' );

$y = &$x; //yはxの参照。ただの代入と違うのは、is_ref=1になること。
xdebug_debug_zval( 'x' );
xdebug_debug_zval( 'y' );


$y = 222; //yを変えると、参照先のxの値が変わるよ。
xdebug_debug_zval( 'x' );
xdebug_debug_zval( 'y' );



echo "----------------そんじゃあ配列で参照使ってみるよ----------------\n";

$ary = array( 1, 2, 3 );
xdebug_debug_zval( 'ary' );

$ref = &$ary[1]; //refは$ary[1]の参照を使うからis_ref=1になるよ
xdebug_debug_zval( 'ary' );
xdebug_debug_zval( 'ref' );


$ref = 333; //refを変えると、参照先の$ary[1]の値が変わるよ。
xdebug_debug_zval( 'ary' );
xdebug_debug_zval( 'ref' );

次に実行結果

C:\Windows\System32>php -v
PHP 5.4.7 (cli) (built: Sep 12 2012 23:48:31)
Copyright (c) 1997-2012 The PHP Group
Zend Engine v2.4.0, Copyright (c) 1998-2012 Zend Technologies
    with Xdebug v2.2.1, Copyright (c) 2002-2012, by Derick Rethans

C:\Windows\System32>php C:\Users\bravewood\Desktop\test.php
a: (refcount=1, is_ref=0)=1
a: (refcount=2, is_ref=0)=1
b: (refcount=2, is_ref=0)=1
a: (refcount=1, is_ref=0)=1
b: (refcount=1, is_ref=0)=111
----------------ここまで代入のみ、ここから参照(&)使うよ----------------
x: (refcount=1, is_ref=0)=1
x: (refcount=2, is_ref=1)=1
y: (refcount=2, is_ref=1)=1
x: (refcount=2, is_ref=1)=222
y: (refcount=2, is_ref=1)=222
----------------そんじゃあ配列で参照使ってみるよ---------------
ary: (refcount=1, is_ref=0)=array (0 => (refcount=1, is_ref=0)=1, 1 => (refcount=1, is_ref=0)=2, 2 => (refcount=1, is_ref=0)=3)
ary: (refcount=1, is_ref=0)=array (0 => (refcount=1, is_ref=0)=1, 1 => (refcount=2, is_ref=1)=2, 2 => (refcount=1, is_ref=0)=3)
ref: (refcount=2, is_ref=1)=2
ary: (refcount=1, is_ref=0)=array (0 => (refcount=1, is_ref=0)=1, 1 => (refcount=2, is_ref=1)=333, 2 => (refcount=1, is_ref=0)=3)
ref: (refcount=2, is_ref=1)=333


参考サイトからの抜粋


参照カウント法の原理
http://php.net/manual/ja/features.gc.refcounting-basics.php

変数を他の変数名に代入すると、refcount が増加します。 
(中略)
この時、refcount は 2 です。なぜなら、同じ変数コンテナが a と b にリンクされるからです。 

代入演算子
http://php.net/manual/ja/language.operators.assignment.php

参照による代入とは、両方の変数が同じデータを指すようにするということです。 データのコピーは発生しません。 

少し説明すると






忙しい人のためのまとめ

  • $ref = &$array[1]; も $b = &$a; も本質的には同じこと
  • 参照による代入とは、両方の変数が同じデータを指すようにするということ
  • var_dumpじゃ参照関係が見えにくい
  • xdebugxdebug_debug_zvalを使うといい


そんなわけでPHPはクソ!!

bravewood the PHPer

Windowsでsymfony2.1をインストールする

http://www.karakaram.com/symfony21-install
http://www.adventar.org/calendars/24
こちらの記事でsymfonyをcomporserでインストールするネタが書かれていて大変参考になるのだが、一つ気になったのが、

Windows では試していません。

ということで、Windowsでインストールする方法を紹介するよ。






必須

  • Apache(今回はXAMPP使います)
  • PHPのPATHが通ってる
  • msysGitがインストール済み

(入れないと途中でgit cloneしようとしてこけます)
インストーラーで簡単に入れれます http://code.google.com/p/msysgit/downloads/list?q=full+installer+official+git





インストール作業


まずディレクトリを作っておく

c:/xampp/htdocs/symfony


ここに comporser.pharをDLしてくる
とりあえず1.0.0-alpha6でいいと思うよ。
http://symfony.com/download
http://getcomposer.org/download/
http://getcomposer.org/download/1.0.0-alpha6/composer.phar

ディレクトリにcomposer.pharだけが存在する状態でOK




mysysgitのGit Bashを立ち上げて

bravewood@PC ~
$ git --version
git version 1.7.10.msysgit.1
bravewood@PC ~
$ cd c:/xampp/htdocs/symfony



インストール

bravewood@PC /c/xampp/htdocs/symfony
$ php composer.phar create-project symfony/framework-standard-edition myproj/ 2.1.4

composerをプロジェクト直下にコピー

bravewood@PC /c/xampp/htdocs/symfony
$ cp composer.phar myproj/







(ここからオプション)


テキストエディタ

C:\xampp\htdocs\symfony\myproj\composer.json

を開いて
以下の4行を追加

    "require": {
...
        "doctrine/data-fixtures": "dev-master",
        "symfony/doctrine-bridge": ">=2.1.0,<2.3-dev",
        "doctrine/doctrine-fixtures-bundle": "dev-master",
        "phpunit/phpunit": "3.7.*"
    },


updateしてバンドルを追加

bravewood@PC /c/xampp/htdocs/symfony
$ cd c:/xampp/htdocs/symfony/myproj

bravewood@PC /c/xampp/htdocs/symfony/myproj
$ php composer.phar update

シンボリックリンクを張る
※WindowsVista以降限定
CMD.exeを右クリックして『管理者として実行』

C:\Windows\system32>cd c:\xampp\htdocs\symfony\myproj
c:\xampp\htdocs\symfony\myproj>mklink phpunit vendor\phpunit\phpunit\composer\bin\phpunit
phpunit ||<===>> vendor\phpunit\phpunit\composer\bin\phpunit のシンボリック リンクが作成されました
c:\xampp\htdocs\symfony\myproj>php ./phpunit --version
PHPUnit 3.7.10 by Sebastian Bergmann.


(ここまでオプション)





ブラウザでアクセス
http://localhost/symfony/myproj/web/app_dev.php

Enjoy Symfony!

VC++2010 ExpressでV8をビルドするお話

ちょっと所用でV8をWindowsでビルドすることになったんだけど、
2012年6月時点でweb上に書かれている方法でやっても上手くいきません。
んで、うまくいく方法を調査したので以下に書きます。



ここの方法そのままではうまくビルドできない
http://code.google.com/p/v8/wiki/BuildingWithGYP

前提

VCは2010 Expressです。
GYPってのを使います。
SConsはもうメンテナンスされていないため使いません。



必要なもの


※2012/07/15 追記 cygwinのインストール要りませんでした。vc以外でインストールが必要なのはpythonのみ(ただし供述のthird_party/cygwinのチェックアウトは必要です)


手順(概要)

cygwinいれる
pythonいれる
pythonパスを通す



必要なソースを落とす
(Unixっぽい記述でかいてますけど全部windows上の話です)

 $ svn checkout http://v8.googlecode.com/svn/trunk/ v8
 $ cd v8
 $ mkdir -p build/gyp
 $ svn co http://gyp.googlecode.com/svn/trunk build/gyp
 $ mkdir -p third_party/cygwin
 $ svn co http://src.chromium.org/svn/trunk/deps/third_party/cygwin third_party/cygwin 
 ※リビジョン 66844 でチェックアウトすること
 $ cp /tmp/vcxproj_include_path_replacer.py .


cygwinターミナル立ち上げて
cygwinファイルシステム上から C:\等にアクセスしたい場合は/cygdrive以下にマウントされているので/cygdriveからパスを始める

 $ cd /cygdrive/c/Users/bravewood/Desktop/v8
 $ build/gyp_v8
 $ python vcxproj_include_path_replacer.py > replace.log


build/all.sln をダブルクリックして開く
F7でソリューション全体をビルド

ビルド結果が

 ========== ビルド: 16 正常終了、0 失敗、0 更新不要、0 スキップ ==========

みたいにエラーなければOK


実行してみる

d8 (v8のシェル)を実行してみたい場合は
\build\Debug\d8.exe
を立ち上げる

V8 version 3.11.10.4 [console: dumb]
d8> var i = 1 + 100;
d8> print( i );
101
d8>quit()

enjoy !