月: 2012年10月

メモ:SymfonyではじめるDIを読んだので実際に写経した。

vol.71は楽しい記事が多いなぁ~。
WEB+DB PRESSでSymfonyではじめるDIを読んだので実際に写経する。

■まずphpのバージョン確認(Composerの兼ね合いで。。)

$ php -v
PHP 5.3.3 (cli) (built: Jul  3 2012 16:40:30)
Copyright (c) 1997-2010 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2010 Zend Technologies

■Composerのインストール

$ curl -s http://getcomposer.org/installer | php
#!/usr/bin/env php
Some settings on your machine may cause stability issues with Composer.
If you encounter issues, try to change the following:

Your PHP (5.3.3) is quite old, upgrading to PHP 5.3.4 or higher is recommended.
Composer works with 5.3.2+ for most people, but there might be edge case issues.

Downloading...

Composer successfully installed to: /path/symfony_DI/composer.phar
Use it: php composer.phar

バージョンで文句言われたけど無視。

■Composer用の設定ファイル作成
$ vim composer.json

{
        "require":{
                "symfony/dependency-injection": "2.1.*",
                "symfony/config": "2.1.*",
                "symfony/yaml": "2.1.*"
        }
}

 

$ ll
total 632
drwxrwxr-x 2 takeuchi takeuchi   4096 Oct 31 15:21 ./
drwxrwxrwx 8 takeuchi takeuchi   4096 Oct 31 15:18 ../
-rw-rw-r-- 1 takeuchi takeuchi    118 Oct 31 15:21 composer.json
-rwxr-xr-x 1 takeuchi takeuchi 631264 Oct 31 15:18 composer.phar*

■依存パッケージの取得

$ php composer.phar install
Loading composer repositories with package information
Installing dependencies
  - Installing symfony/dependency-injection (v2.1.3)
    Downloading: 100%

  - Installing symfony/config (v2.1.3)
    Downloading: 100%

  - Installing symfony/yaml (v2.1.3)
    Downloading: 100%

Writing lock file
Generating autoload files
$ ll
total 644
drwxrwxr-x 3 takeuchi takeuchi   4096 Oct 31 15:23 ./
drwxrwxrwx 8 takeuchi takeuchi   4096 Oct 31 15:18 ../
-rw-rw-r-- 1 takeuchi takeuchi    118 Oct 31 15:21 composer.json
-rw-rw-r-- 1 takeuchi takeuchi   4939 Oct 31 15:23 composer.lock
-rwxr-xr-x 1 takeuchi takeuchi 631264 Oct 31 15:18 composer.phar*
drwxrwxr-x 4 takeuchi takeuchi   4096 Oct 31 15:23 vendor/

■依存のないクラスの実装とかそれ以降のコード
$ vim initial.php

namespace App{
         class Controller{
                private $memberRegistration;
                private $router;
                private $templating;
                public function __construct(){
                        echo __METHOD__.PHP_EOL;
                }
                public function registerAction(){
                        echo __METHOD__.PHP_EOL;
                        $memberData=$this->getRequestData();
                        $this->memberRegistration->register($memberData);
                        $html=$this->templating->render('register');
                        return $html;
                }
                public function setMemberRegistration(\Domain\MemberRegistration $memberRegistration){
                        echo __METHOD__.PHP_EOL;
                        $this->memberRegistration=$memberRegistration;
                }
                public function setRouter(\App\Router $router){
                        echo __METHOD__.PHP_EOL;
                        $this->router=$router;
                }
                public function setTemplating(\App\Templating $templating){
                        echo __METHOD__.PHP_EOL;
                        $this->templating=$templating;
                }
                private function getRequestData(){
                        return array();
                }

        }

        class Templating{
                private $router;
                public function __construct(){
                        echo __METHOD__.PHP_EOL;
                }
                public function render($templateName){
                        echo __METHOD__.PHP_EOL;
                        $url=$this->router->generateUrl('test');
                }
                //セッターインジェクション
                public function setRouter(\App\Router $router){
                        $this->router=$router;
                }
        }

        class Router{
                public function __construct(){
                        echo __METHOD__.PHP_EOL;
                }
                public function generateUrl(){
                        echo __METHOD__.PHP_EOL;
                }
        }
}

namespace Domain{
        class MemberRegistration{
                public function __construct(){
                        echo __METHOD__.PHP_EOL;
                }
                public function register($memberData){
                        echo __METHOD__.PHP_EOL;
                }
        }
}

namespace{
        require_once 'vendor/autoload.php';
        use Symfony\Component\DependencyInjection\ContainerBuilder;
        use Symfony\Component\DependencyInjection\Reference;

        $container=new ContainerBuilder();

        $container->register('app.controller', '\App\Controller')
                ->addMethodCall('setTemplating', array(new Reference('app.templating'),))
                ->addMethodCall('setRouter', array(new Reference('app.router'),))
                ->addMethodCall('setMemberRegistration', array(new Reference('domain.member_registration'),));

        $container->register('app.templating', '\App\Templating')
                ->addMethodCall('setRouter', array(new Reference('app.router'),));

        $container->register('app.router', '\App\Router');

        $container->register('domain.member_registration', '\Domain\MemberRegistration');

        $controller=$container->get('app.controller');
        $controller->registerAction();
}

■実行結果

$ php initial.php
App\Controller::__construct
App\Templating::__construct
App\Router::__construct
App\Controller::setTemplating
App\Controller::setRouter
Domain\MemberRegistration::__construct
App\Controller::setMemberRegistration
App\Controller::registerAction
Domain\MemberRegistration::register
App\Templating::render
App\Router::generateUrl

このあとはYAMLにしたりダンプで再利用とか。

■参考URL
PHPの外部ライブラリの管理にComposerを使う

HerokuでPHP

HerokuでPHP

WEB+DB PRESSのvol.71のHeroku特集を見てRailsで試してみたけど
PHPも動くらしいのでやってみた。

Play framework2を試すはずなのに脱線しまくり。

ではHerokuでPHPを動かしてみる。
Herokuのアカウント持ってて、herokuコマンドインストール済みのログイン済みで以下。

$ mkdir myapp
$ cd myapp/
$ git init
Initialized empty Git repository in /path/myapp/.git/
$ vim index.php
<?php echo "Hello Heroku!!";

phpinfo();

?>
$ git add .
$ git commit -m "first commit"
[master (root-commit) 024c43b] first commit
 1 files changed, 1 insertions(+), 0 deletions(-)
 create mode 100644 index.php
$ heroku create --stack cedar
Creating evening-chamber-8448... done, stack is cedar
http://evening-chamber-8448.herokuapp.com/ | git@heroku.com:evening-chamber-8448.git
Git remote heroku added
$ git push heroku master
Counting objects: 3, done.
Writing objects: 100% (3/3), 252 bytes, done.
Total 3 (delta 0), reused 0 (delta 0)

-----> Heroku receiving push
-----> PHP app detected
-----> Bundling Apache version 2.2.22
-----> Bundling PHP version 5.3.10
-----> Discovering process types
       Procfile declares types -> (none)
       Default types for PHP   -> web
-----> Compiled slug size: 9.5MB
-----> Launching... done, v4
       http://evening-chamber-8448.herokuapp.com deployed to Heroku

To git@heroku.com:evening-chamber-8448.git
 * [new branch]      master -> master

今回であれば以下にブラウザでアクセスすれば表示されるはず(もう消したけど)
http://evening-chamber-8448.herokuapp.com/

すっごい簡単。。

※index.php置かないと

-----> Heroku receiving push
 !     Heroku push rejected, no Cedar-supported app detected

To git@heroku.com:laxherokuphptest.git
 ! [remote rejected] master -> master (pre-receive hook declined)
error: failed to push some refs to 'git@heroku.com:laxherokuphptest.git'

とか言われるので注意。

で実際にphpinfoを見てみるとmbstringが無いのでググって調べる。

herokuで(mbstring有効な)phpがすぐ動いた

HerokuのBuildpackを利用してmbstringが有効なPHPサーバを立ててみた

buildpackを使ってみればいいのか。
ということでもう一度再挑戦。

$ mkdir myapp
$ cd myapp/
$ git init
Initialized empty Git repository in /path/myapp/.git/
$ vim index.php
<?php echo "Hello Heroku!!";

phpinfo();

?>
$ git add .
$ git commit -m "first commit"
[master (root-commit) 1dca1f5] first commit
 1 files changed, 5 insertions(+), 0 deletions(-)
 create mode 100644 index.php
$ heroku create --buildpack https://github.com/winglian/heroku-buildpack-php -s cedar
Creating stark-wildwood-1510... done, stack is cedar
BUILDPACK_URL=https://github.com/winglian/heroku-buildpack-php
http://stark-wildwood-1510.herokuapp.com/ | git@heroku.com:stark-wildwood-1510.git
Git remote heroku added
$ git push heroku master
Counting objects: 3, done.
Writing objects: 100% (3/3), 261 bytes, done.
Total 3 (delta 0), reused 0 (delta 0)

-----> Heroku receiving push
-----> Fetching custom git buildpack... done
-----> PHP app detected
-----> Extracting Apache 2.4.3 PHP 5.4.8 build 2.0-a4
-----> from http://vulcan-wlian.herokuapp.com/output/b8bace2a-2a8e-4441-acc3-eb8e6ad608a5
Creating Slug Identifier file with id: c24ac748141520640ed3220f65e2cde0
-----> Discovering process types
       Procfile declares types -> (none)
       Default types for PHP   -> web
-----> Compiled slug size: 10.3MB
-----> Launching... done, v5
       http://stark-wildwood-1510.herokuapp.com deployed to Heroku

To git@heroku.com:stark-wildwood-1510.git
 * [new branch]      master -> master

mbstring入ったーbuildpackすげー。
というかこのbuildpack PHP5.4.8だし

herokuでPHP面白いかも。

こんなのも見つけた。

mhoofman / wordpress-heroku

Symfony2 on heroku (other php frameworks too)

jstdutilをインストールした

jstdutilをインストールしたい。

jstdutilは↓を提供してくれる便利なやつ。
・JsTestDriverのコマンドラインを簡略化するjstestdirver
・ファイル更新時に自動的にテストを実行するjsautotest

jstdutilはrubyのgemからインストールできるらしい。
でもそもそもrubyすら入っていない・・・。
とりあえず手元にあったCentOS release 5.7にrubyを入れる。

yumで見たらVersionが1.8.5だった・・・。

# yum info ruby
Loaded plugins: fastestmirror, security
Loading mirror speeds from cached hostfile
 * base: ftp.iij.ad.jp
 * extras: ftp.iij.ad.jp
 * updates: ftp.iij.ad.jp
base                                                                                                                                  | 1.1 kB     00:00
extras                                                                                                                                | 1.9 kB     00:00
updates                                                                                                                               | 1.9 kB     00:00
updates/primary_db                                                                                                                    | 837 kB     00:00
vz-base                                                                                                                               |  951 B     00:00
vz-updates                                                                                                                            |  951 B     00:00
Available Packages
Name       : ruby
Arch       : i386
Version    : 1.8.5
Release    : 24.el5
Size       : 277 k
Repo       : base
Summary    : An interpreter of object-oriented scripting language
URL        : http://www.ruby-lang.org/
License    : Ruby License/GPL - see COPYING
Description: Ruby is the interpreted scripting language for quick and easy
           : object-oriented programming.  It has many features to process text
           : files and to do system management tasks (as in Perl).  It is simple,
           : straight-forward, and extensible.

rubyのサイトを見るとどうやら最新の安定版は「ruby 1.9.3-p286」らしいので
ソースからビルドしてみる。

Ruby Install Guide::UNIX全般

↑このとおりやってみた。

で、今回の目的だった「jstdutil」を入れようとする。

$ gem install jstdutil

入ったのかな?よくわかんないので動かしてみる。

$ jsautotest
/usr/local/lib/ruby/1.9.1/yaml.rb:56:in `<top (required)>':
It seems your ruby installation is missing psych (for YAML output).
To eliminate this warning, please install libyaml and reinstall your ruby.
/usr/local/lib/ruby/gems/1.9.1/gems/watchr-0.7/lib/watchr.rb:111: Use RbConfig instead of obsolete and deprecated Config.
Using config file public_html/Javascript/JsTestDriver.conf
An error occurred
invalid byte sequence in UTF-8

どうも怒られているらしい。

Ruby 1.9.3 を導入するにあたってソースからビルドする人が気をつける事とはいったい…?!

上記サイトの内容に沿って最新のlibyamlをいれてrubyをconfigure;make;make install

$ java -jar  $JSTESTDRIVER_HOME/JsTestDriver-1.3.5.jar --port 4224
setting runnermode QUIET

サーバ立てて・・・ブラウザで「Capture This Browser」クリックして・・・

$ jstestdriver --config=path/JsTestDriver.conf --tests all
setting runnermode QUIET
.......
Total 7 tests (Passed: 7; Fails: 0; Errors: 0) (2.00 ms)
  Microsoft Internet Explorer 9.0 Windows: Run 7 tests (Passed: 7; Fails: 0; Errors 0) (2.00 ms)

動いた。でも相変わらず jsautotest はだめ

$ jsautotest
/usr/local/lib/ruby/gems/1.9.1/gems/watchr-0.7/lib/watchr.rb:111: Use RbConfig instead of obsolete and deprecated Config.
Using config file public_html/Javascript/JsTestDriver.conf
An error occurred
invalid byte sequence in UTF-8

よくわかんないけどwatcharとかいうのを入れてみる。

# gem install watchr
Successfully installed watchr-0.7
1 gem installed
Installing ri documentation for watchr-0.7...
Installing RDoc documentation for watchr-0.7...

さらに、、、どうもコンフィグのファイル名が悪いらしいのでファイル名を変更
「JsTestDriver.conf」から「jstestdriver.conf」

で今一度

$ jsautotest
/usr/local/lib/ruby/gems/1.9.1/gems/watchr-0.7/lib/watchr.rb:111: Use RbConfig instead of obsolete and deprecated Config.
Using config file jstestdriver.conf

おっ動いたかも。
この状態でテストケースとかを変更してみる。。。。すると。

$ jsautotest
/usr/local/lib/ruby/gems/1.9.1/gems/watchr-0.7/lib/watchr.rb:111: Use RbConfig instead of obsolete and deprecated Config.
Using config file jstestdriver.conf
2012-10-29 15:14:14 Running all
setting runnermode QUIET
Microsoft Internet Explorer: Reset
Microsoft Internet Explorer: Reset
.......
Total 7 tests (Passed: 7; Fails: 0; Errors: 0) (3.00 ms)
  Microsoft Internet Explorer 9.0 Windows: Run 7 tests (Passed: 7; Fails: 0; Errors 0) (3.00 ms)

おー動いた。rubyよくわかんないっす。。

JsTestDriverで「Oh Snap! No server defined!」って出た。

JsTestDriverで「Oh Snap! No server defined!」って出た。

テスト駆動Javascriptを読んでて「JsTestDriver」を導入しようと思って設定してたら
java.lang.RuntimeException: Oh Snap! No server defined!
っていうエラーが出た話。

そもそもの「JsTestDriver」の導入方法はアシアルさんが丁寧に書いてくれているのでそれを真似る。
windows版では問題なく動いたんだけどCentOS5の環境でやろうとしたらエラー出たという。。

アシアルさん:JsTestDriverで簡単テスト

■実際にエラーになったコマンド

$ java -jar $JSTESTDRIVER_HOME/JsTestDriver-1.3.5.jar --tests all
setting runnermode QUIET
java.lang.RuntimeException: Oh Snap! No server defined!
        at com.google.jstestdriver.config.DefaultConfiguration.getServer(DefaultConfiguration.java:61)
        at com.google.jstestdriver.config.Initializer.initialize(Initializer.java:99)
        at com.google.jstestdriver.embedded.JsTestDriverImpl.createRunnerInjector(JsTestDriverImpl.java:368)
        at com.google.jstestdriver.embedded.JsTestDriverImpl.runConfigurationWithFlags(JsTestDriverImpl.java:342)
        at com.google.jstestdriver.embedded.JsTestDriverImpl.runConfiguration(JsTestDriverImpl.java:233)
        at com.google.jstestdriver.Main.main(Main.java:70)
Unexpected Runner Condition: Oh Snap! No server defined!
 Use --runnerMode DEBUG for more information.

■今回のフォルダ構成

jarファイル

/home/myname/bin/
`– JsTestDriver-1.3.5.jar

ソースとテストファイル

/home/myname/public_html/Javascript/
|– JsTestDriver.conf
|– src
| `– sample.js
`– test
`– sample.js

どうも原因はconfファイルを見つけられなかったことらしい。
なので明示的に対対象の設定ファイルの場所を「–config」オプションで指定するようにする。
※絶対パスで指定してるけど別に相対でも可。

$ java -jar $JSTESTDRIVER_HOME/JsTestDriver-1.3.5.jar --config /home/myname/public_html/Javascript/JsTestDriver.conf --tests all
setting runnermode QUIET
..
Total 2 tests (Passed: 2; Fails: 0; Errors: 0) (1.00 ms)
  Microsoft Internet Explorer 9.0 Windows: Run 2 tests (Passed: 2; Fails: 0; Errors 0) (1.00 ms)

動いたー!

■参考URL

JsTestDriverで簡単テスト

java.lang.RuntimeException: Oh Snap! No server defined!

JsTestDriver導入

OpenVZのCentOS6(guest)でyum-fastestmirrorのエラーが出た。

OpenVZのCentOS6(guest)でyum-fastestmirrorのエラーが出た。

実験機のOpenVZのゲストにjavaを入れようとしたらyumでエラーが出た。

# yum search java
Loaded plugins: fastestmirror
Determining fastest mirrors
Traceback (most recent call last):
  File "/usr/bin/yum", line 29, in <module>
    yummain.user_main(sys.argv[1:], exit_code=True)
  File "/usr/share/yum-cli/yummain.py", line 285, in user_main
    errcode = main(args)
  File "/usr/share/yum-cli/yummain.py", line 136, in main
    result, resultmsgs = base.doCommands()
  File "/usr/share/yum-cli/cli.py", line 438, in doCommands
    return self.yum_cli_commands[self.basecmd].doCommand(self, self.basecmd, self.extcmds)
  File "/usr/share/yum-cli/yumcommands.py", line 686, in doCommand
    return base.search(extcmds)
  File "/usr/share/yum-cli/cli.py", line 1030, in search
    for (po, keys, matched_value) in matching:
  File "/usr/lib/python2.6/site-packages/yum/__init__.py", line 2540, in searchGenerator
    for sack in self.pkgSack.sacks.values():
  File "/usr/lib/python2.6/site-packages/yum/__init__.py", line 897, in <lambda>
    pkgSack = property(fget=lambda self: self._getSacks(),
  File "/usr/lib/python2.6/site-packages/yum/__init__.py", line 682, in _getSacks
    self.repos.populateSack(which=repos)
  File "/usr/lib/python2.6/site-packages/yum/repos.py", line 265, in populateSack
    self.doSetup()
  File "/usr/lib/python2.6/site-packages/yum/repos.py", line 92, in doSetup
    self.ayum.plugins.run('postreposetup')
  File "/usr/lib/python2.6/site-packages/yum/plugins.py", line 184, in run
    func(conduitcls(self, self.base, conf, **kwargs))
  File "/usr/lib/yum-plugins/fastestmirror.py", line 202, in postreposetup_hook
    all_urls = FastestMirror(all_urls).get_mirrorlist()
  File "/usr/lib/yum-plugins/fastestmirror.py", line 369, in get_mirrorlist
    self._poll_mirrors()
  File "/usr/lib/yum-plugins/fastestmirror.py", line 413, in _poll_mirrors
    pollThread.start()
  File "/usr/lib/python2.6/threading.py", line 474, in start
    _start_new_thread(self.__bootstrap, ())
thread.error: can't start new thread

とりあえず「yum clean all」するも駄目。

# yum clean all
Loaded plugins: fastestmirror
Cleaning repos: base extras updates vz-base vz-updates
Cleaning up Everything
Cleaning up list of fastest mirrors

fastestmirrorが悪いのかな?と思い以下を実行

# rpm -ev --nodeps fastestmirror
error: package yum-fastestmirror is not installed

そんなのは無いといわれる。

色々調べてみたところ同じような現象に遭遇していた人がいたので
そこのブログの内容を参考に対応してみる。

要するに、VPSだとyumでメモリ不足の問題が発生する事が多いから、
fastestmirror pluginは使わないでね、という事みたいですね。

ということなので同じように「–disablepplugin」してみる。

# yum --disableplugin=fastestmirror search java

できた!

こっちもおんなじ用に毎回「–disablepplugin」するの面倒なので
削除を試みる。

# rpm -qa | grep yum
yum-3.2.29-30.el6.centos.noarch
yum-metadata-parser-1.1.2-16.el6.i686
yum-plugin-fastestmirror-1.1.30-14.el6.noarch
# rpm -ev --nodeps yum-plugin-fastestmirror-1.1.30-14.el6.noarch
# yum search java

出来た

■参考URL

yumでyum-fastestmirrorのエラーAdd Star

[DTI ServersMan@VPS]yum updateで早速エラーですよ。

PHPプログラム中でapacheユーザでchownする方法

PHPプログラム中でapacheユーザでchownする方法

PHPでブラウザからプログラムを動かして、
作成したファイルやフォルダの権限を変更したい場合のやり方。

通常はapacehユーザでファイルやフォルダが作成
されてしまうのでプログラム中でchownを実行したいの
だけれど、chownはrootで動かさないとなのでこのまま
単純にchownを実行しても権限やグループを変えることが
できない。

そこで、sudoでapacheユーザに特定のコマンドだけを許すように設定
を変更する。

# visudo

apache ALL=(ALL) NOPASSWD: /bin/mkdir, /bin/chown

上記の場合はapacheユーザにパスワード無しで「mkdir」と「chown」の実行を許可している。
他のコマンドも許可したければ、続けて記述していけばOK。

これで大丈夫かなと思って実行してみたらchownで変更できていない。
エラーログを見ると以下のメッセーが・・・。

「sudo: sorry, you must have a tty to run sudo」

SSHクライアントとかコンソールではエラーが出ないのに。。。
調べてみると「Defaults requiretty」をコメントアウトすればいいことが判明。

# visudo

Defaults requiretty
↓
#Defaults requiretty

するとエラーが出なくなり、無事にchownが実行できた。

■参考URL

Apacheユーザーでsudo

TTY経由でないsudoの実行

アドレスの統一(index.html有り版)

アドレスの統一(index.html有り)

前回のエントリではindex.html無しにする場合だったので
index.html有りにする場合も書いておく。

.htaccessの記述

RewriteEngine on

#TOPページの処理
RewriteRule ^$ http://example.com/index.html [R=301,L]

#下層ページの処理
#ただし/xxxxxxxx/のURLは除外
RewriteCond %{THE_REQUEST} !^.*/xxxxxxxx/
RewriteCond %{THE_REQUEST} ^.*/
RewriteRule ^(.*)/$ http://example.com/$1/index.html [R=301,L]

※除外的なものも入れてる。