‘PHP’ カテゴリーのアーカイブ

phpenv+php-build+pyrusでの複数バージョンPHP管理など

必要なもの

  • phpenv
    PHPのバージョン切り替え(切り替えるのみ、PHPのインストールはできない。rbenvを流用)
  • php-build
    複数バージョンPHPのインストールマネージャ
  • Pyrus
    PEAR後継パッケージマネージャ

phpenvのインストール

$ curl https://raw.github.com/CHH/phpenv/master/bin/phpenv-install.sh | sh
Installing phpenv in /Users/dataich/.phpenv
remote: Counting objects: 1008, done.
remote: Compressing objects: 100% (422/422), done.
remote: Total 1008 (delta 633), reused 928 (delta 558)
Receiving objects: 100% (1008/1008), 135.47 KiB | 124 KiB/s, done.
Resolving deltas: 100% (633/633), done.
Success.

Now add /Users/dataich/.phpenv/bin to your $PATH, add "eval $(phpenv init -)" at the end of your ~/.bashrc and restart your shell to use phpenv.

最後の行で言われたとおり、.bashrcに追記します。

$ vi ~/.bashrc
export PATH="/Users/dataich/.phpenv/bin:$PATH"
eval "$(phpenv init -)"

phpenvは~/.phpenv以下にインストールされており、~/.phpenv/versionsにバージョンごとのPHPをインストールしてやることで切り替えが可能になります。

php-buildのインストール

$ git clone https://github.com/CHH/php-build.git
$ cd php-build
$ ./install.sh
Installing php-build in /usr/local
- Creating Directories... Done.
- Copying files... Done.

これで必要なもののインストールは完了です。また、現状はインストールできるPHPバージョンが増えたりした場合は、git pullして./install.shを再度実行しないといけないと思います。

php-buildを使用してPHPをインストール

まずはインストール可能なバージョンを調べます。

$ php-build --definitions
5.2.17
5.3.2
5.3.6
5.3.8
5.3.9RC3
5.3snapshot
5.4.0RC1
5.4.0RC2
5.4.0RC3
5.4.0RC4
5.4.0alpha3
5.4.0beta1
5.4.0beta2
5.4snapshot

では上記から好きなバージョンを選んでインストールしています。今回は業務で必須なので5.3.8を。

とその前にApacheモジュールどうする?

php-buildはApacheモジュールのビルドに対応していません(GitHubにIssueにはFeatureとして登録されてます。)。
ソースを読んでみるconfigure_optionを呼び出してあげればよさそうです。なのでdefinitionsに定義してあるスクリプトに変更を入れてあげます。このdefinitions配下にあるスクリプトはいろいろビルド方法を調整する時に使えそうです(pyrusじゃなくてpear使いたかったらwith_pear書いて、install_pyrusコメントアウトするとか。)

$ vi /usr/local/share/php-build/definitions/5.3.8
configure_option "--with-apxs2" "/usr/local/Cellar/httpd/2.2.21/sbin/apxs" #この行を追加する。apxsへのパスは環境に応じて置き換えてください。
install_package "http://www.php.net/distributions/php-5.3.8.tar.bz2"
install_pyrus

install_xdebug "2.1.2"

まあPHPをビルドする度にlibphp5.soを上書きしてしまうだろうということと、phpenvで切り替えた時どうするのっていうのはありますが・・・。

気をとりなおしてphp-buildを使用してPHPをインストール

ではphp-buildを使用して5.3.8をインストールします。プレフィックスには~/.phpenv/versions/5.3.8を指定します。実はここでちょっとはまったのですが、最後の引数はプレフィックスなのでフルパスである必要があります。

$ php-build 5.3.8 ~/.phpenv/versions/5.3.8
Loaded pyrus Plugin.
Loaded xdebug Plugin.
php.ini-production gets used as php.ini

Building 5.3.8 into /Users/dataich/.phpenv/versions/5.3.8

[Downloading]: http://www.php.net/distributions/php-5.3.8.tar.bz2
[Configure]: /usr/local/bin/../tmp/php-build/source/5.3.8
[Make]: /usr/local/bin/../tmp/php-build/source/5.3.8
[Pyrus]: Downloading from http://pear2.php.net/pyrus.phar
[Pyrus]: Installing executable in /Users/dataich/.phpenv/versions/5.3.8/bin/pyrus
[XDebug]: Downloading http://xdebug.org/files/xdebug-2.1.2.tgz
[XDebug]: Compiling in /usr/local/bin/../tmp/php-build/source/xdebug-2.1.2
[XDebug]: Installing XDebug configuration in /Users/dataich/.phpenv/versions/5.3.8/etc/conf.d/xdebug.ini
[XDebug]: Cleaning up.
[Info]: The Log File is not empty, but the Build did not fail. Maybe just warnings got logged. You can review the log in /usr/local/bin/../var/log/php-build/error.5.3.8.20120106174319.log
[Success]: Built 5.3.8 successfully.

ちなみにphp.iniは~/.phpenv/versions/5.3.8/etc配下のを使うようになっています。また~/.phpenv/versions/5.3.8/etc/conf.d配下のものも読むようになっており、xdebug.iniなどが置いてあります。バージョンごとにiniファイルを持っているので便利です。

phpenvを使ってみる

ではphpenvにて切り替えられるバージョンを調べてみます。

$ phpenv versions
5.3.8

先ほどインスールした5.3.8が使用できる状態になっていますので、グローバルに使うようにします。

$ phpenv global 5.3.8
$ phpenv versions
* 5.3.8 (set by /Users/dataich/.rbenv-version)
$ php -v
PHP 5.3.8 (cli) (built: Jan 11 2012 23:20:46)
Copyright (c) 1997-2011 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2011 Zend Technologies
with Xdebug v2.1.2, Copyright (c) 2002-2011, by Derick Rethans

また、下記のようにlocalを使うとカレントディレクトリに.rbenv-versionというファイルが作られ、そのディレクトリ配下では一度指定したバージョンが使われるようになります。

$ phpenv local 5.4snapshot

phpenv rehashコマンド

phpenvでは.phpenv/shims/にパスを通すようになっており、そこを介してexecutableなコマンドを実行したりします。

$ ll .phpenv/shims

何もないはずです。ここを構築するにはrehashを使います。

$ phpenv rehash
$ ll .phpenv/shims/
total 56
-rwxr-xr-x 7 dataich staff 102 1 11 23:31 phar
-rwxr-xr-x 7 dataich staff 102 1 11 23:31 phar.phar
-rwxr-xr-x 7 dataich staff 102 1 11 23:31 php
-rwxr-xr-x 7 dataich staff 102 1 11 23:31 php-config
-rwxr-xr-x 7 dataich staff 102 1 11 23:31 phpize
-rwxr-xr-x 7 dataich staff 102 1 11 23:31 pyrus
-rwxr-xr-x 7 dataich staff 102 1 11 23:31 pyrus.phar

これを実行することでインストールされているPHPやPEARモジュールの実体を探してきて、シムリンクぽいシェルスクリプトが作成されます。新しいバージョンのPHPや、phpunitなどの実行モジュールをインストールした後には実行しておきましょう。

Pyrus

で次にPyrusです。PEARの後継にあたるパッケージマネージャです。使ってみます。
php-buildでインストールした際に既に使えるようになっています。

$ pyrus config-show
Pyrus version 2.0.0a3 SHA-1: BE7EA9D171AE3873F1BBAF692EEE9165BB14BD5D
Using PEAR installation found at /Users/dataich/.phpenv/versions/5.3.8/pyrus
System paths:
php_dir => /Users/dataich/.phpenv/versions/5.3.8/pyrus/php
ext_dir => /Users/dataich/.phpenv/versions/5.3.8/lib/php/extensions/no-debug-non-zts-20090626
cfg_dir => /Users/dataich/.phpenv/versions/5.3.8/pyrus/cfg
doc_dir => /Users/dataich/.phpenv/versions/5.3.8/pyrus/docs
bin_dir => /Users/dataich/.phpenv/versions/5.3.8/bin/
data_dir => /Users/dataich/.phpenv/versions/5.3.8/pyrus/data
www_dir => /Users/dataich/.phpenv/versions/5.3.8/pyrus/www
test_dir => /Users/dataich/.phpenv/versions/5.3.8/pyrus/tests
src_dir => /Users/dataich/.phpenv/versions/5.3.8/pyrus/src
php_bin => /Users/dataich/.phpenv/versions/5.3.8/bin/php
php_ini => /Users/dataich/.phpenv/versions/5.3.8/etc/php.ini
php_prefix => /Users/dataich/.phpenv/versions/5.3.8/bin/
php_suffix =>
...

パッケージのインストール先ディレクトリ等がphpenvで指定している現在のバージョン配下になっています、素晴らしい!これでPEARモジュールは現在使用中のPHPのバージョン配下に収まることになります。

pyrusコマンドは第一引数にディレクトリを渡してやることで、そのディレクトリローカルなパッケージ管理ができるようになるので、非常に便利です。ただphp-buildが生成するshimにバグがあって、使えない状態だったのですが、作者さんに投げたところ数時間で対応していただきました、これで常用できそうです。
#35: Cannot use pyrus locally – Issues – CHH/php-build – GitHub

ただし現状Pyrusだとプロジェクトローカルなインストールは簡単なのですが、依存関係の設定ファイルだけリポジトリに上げておいて、コマンド一発で全部インストールみたいなことが難しいです。package.xmlを作ればできるようなのですが、そもそもPEARモジュールのビルド用ぽくて、扱いが難しいです。次のエントリーではその辺りを上手く解決してくれる、Onion、Composer辺り扱ってみます。

参考

phpenv で複数の PHP 環境を管理する
php-build で PHP 5.4.0 beta1 をビルドする
Using Pyrus To Manage PEAR Installable Vendor Libs

Facebooktwitterlinkedintumblrmail

PHPUnit_Storyで振舞駆動開発なテストを書いてみた

テスト対象としてEntryクラスを作成しました。

  • ステータス(下書き・公開済・削除)を持つ。
  • 初期ステータスは下書き
  • ステータスはメソッドを通じて変更できる。

まずはテスト駆動開発なテストを行う簡単なテストケースを書いてみました。こんなコードになります。

実行結果はこうなります。
$ phpunit --debug EntryTest.php 
PHPUnit 3.6.2 by Sebastian Bergmann.


Starting test 'EntryTest::testStatus'.
.

Time: 0 seconds, Memory: 5.50Mb

OK (1 test, 3 assertions)

これを振舞駆動開発なテストで書きなおしてみました。PHPUnit_Extensions_Story_TestCaseをextendsし、runGiven、runWhen、runThenを実装する必要があります。

実行結果はこうです。なんかそれっぽくなりました
$ phpunit --debug --verbose --printer PHPUnit_Extensions_Story_ResultPrinter_Text EntrySpec.php
PHPUnit 3.6.2 by Sebastian Bergmann.

EntrySpec
 [x] Status for new entry is draft

   Given New Entry 
    Then Status should be draft

 [x] Status after publish entry is published

   Given Some Entry 
    When publish Entry 
    Then Status should be published

 [x] Status after delete entry is deleted

   Given Some Entry 
    When delete Entry 
    Then Status should be deleted

Scenarios: 3, Failed: 0, Skipped: 0, Incomplete: 0.

パッと見、コード量が多くなってしまいましたが、テスト対象がサンプル程度なので。実装が増えてきたときに、runGiven、runWhen、runThenを良い感じに使いまわせるようにすると、効果大きそうです。
ちなみにPHPUnit、PHPUnit_StoryともにPEARでサクッとインストール可能です。

Facebooktwitterlinkedintumblrmail

HomebrewでApache2.2+MySQL5.1+PHP5.3環境を構築

残念ながらHomebrewのリポジトリにはApache、PHPがなく、MySQLは5.5となっています。もっともApacheとPHPに関しては、システムに入ってるものはインストールしないというHomebrewの方針なんだろうと思いますが。で探し回っているとこんなものを見つけました。

Alternate formulae repos for Homebrew
https://github.com/adamv/homebrew-alt/

homebrewのリポジトリにはないものを野良的に公開してくださっています。上記利用させていただいて、MAMP環境を構築します。

PHP5.3のインストール

HomebrewはFomulaの直URL指定でもインストールすることができます。

brew install https://raw.github.com/adamv/homebrew-alt/master/duplicates/php.rb --with-mysql

ちなみにduplicatesディレクトリに入っているFomulaは、OS Xに標準で入っているものが集められています。

MySQL5.1のインストール

brew install https://raw.github.com/adamv/homebrew-alt/master/versions/mysql51.rb --with-utf8-default --use-gcc
初期設定
unset TMPDIR
mysql_install_db
起動・停止

私は、自動起動はさせたくなかったので、launchdには登録しませんでした。

mysql.server start
mysql.server stop

Apache2.2のインストール

brew install https://raw.github.com/adamv/homebrew-alt/master/duplicates/httpd.rb

httpd.conf等は/usr/local/Cellar/httpd/2.2.21/etc/apache2にあります。

PHPなどの設定

私の場合は、extra/php.confを作成し、httpd.confにてIncludeするようにしています。

vi /usr/local/Cellar/httpd/2.2.21/etc/apache2/extra/php.conf
LoadModule php5_module /usr/local/Cellar/php/5.3.8/libexec/apache2/libphp5.so
AddType application/x-httpd-php .php .php5 .phtml

その他に、DocumentRootを/Users/dataich/Sitesという風にユーザーホームのSitesディレクトリを使用するようにしました。この辺りはお好みで。

起動・停止
sudo apachectl start
sudo apachectl stop

あとは、phpinfo()で出力してみたりして確認すればOKです。

追記 – 2011/11/08
Homebrewで入れたPHPのpearでpermissionエラーが出ましたので、下記でもろもろ設定しました。

chmod -R ug+w /usr/local/Cellar/php/5.3.8/lib/php
pear config-set php_ini /usr/local/etc/php.ini
Facebooktwitterlinkedintumblrmail

WordPressで記事に挿入するタイミングで画像のサイズを制限する

WordPressでこんなシチュエーションに出くわしました。

  • アップロードする画像のサイズには制限をかけたくない。
  • というのも画像クリック時にはなるべく大きな画像をthickboxとかで表示したい。
  • ただそれだと、投稿にフルサイズ指定で挿入されるとdivをはみ出したりしてしまう。
  • たくさんのユーザが投稿するサイトなので、いちいちミディアム指定を説明したくない。

ありました、投稿に挿入する時のサイズを制限するためのeditor_max_image_sizeというフィルタフックが。
というわけで

function filter_editor_max_image_size() {
  return array(500, 500);
}
add_filter('editor_max_image_size', 'filter_editor_max_image_size');

これでフルサイズを画面から指定されても、最大で500までのwidthとなりますのでOKです。
困った時はWordpressのソースを追って、apply_filterやdo_actionを探せば、本体に手を入れずに拡張できますね。

Facebooktwitterlinkedintumblrmail

WordPressをGitで管理する時の.gitignore

現在進行中のプロジェクトにて、WordpressをGitで管理しているのですが、
その際の.gitignoreを晒しておきます。
基本的にはwp-contents/uploads(投稿画像など)以下を除外しておけばOKです。

wp-config.php
wp-content/uploads/*
!wp-content/uploads/wptouch/

最後の行がミソで、uploads以下は除外したいけども、プラグインWPtouch用のカスタムアイコンがここに置かれるので、
それはコミットしたい。そういう時は「!」で否定してあげればOKです。

敢えて今回はwp-content/plugins等はGitで管理下においていますが、シチュエーションに合わせましょう。

Facebooktwitterlinkedintumblrmail

CORESERVERからdotCloudにWordPressをお引っ越し

dotCloudがプライベートベータから正式リリースに至り、ベータの頃からのユーザには1年間のProアカウントを発行してくれるということで、PaaSの運用テストを兼ねて、引っ越してみることにしました。個人ではお高いのでずっとは使えませんが。。。

CORESERVERでやること

まずは、CORESERVER側のWordpressを本体、プラグインともに最新にアップデートしました。
この状態でCORESERVERの管理画面からWordpressデータベースのダンプを取ってローカルに持ってきます。
また、CORESERVER上のWordpressディレクトリもごっそりローカルに持ってきました。

dotCloud基本設定

ここからがdotCloudに対して行う作業です。
ここではアプリケーション名をwordpressとしています。

dotCloudにアプリケーションを作成します。

dataich:dev dataich$ dotcloud create wordpress
Created application "wordpress"

ローカルにディレクトリを作成します。

dataich:dev dataich$ mkdir blog.dataich.com

ここにサービスの設定や、ソースコード等を置いていきます。

WordPressに必要なサービスPHP、MySQLの設定を行います。dotcloud.ymlに記述します。

dataich:dev dataich$ vi blog.dataich.com/dotcloud.yml

まずはこの状態で動きを確認してみます。 dotcloud pushコマンドでアプリケーションのソースコード(とはいってもこの段階ではdotcloud.ymlのみ)をPushします。

dataich:dev dataich$ dotcloud push wordpress blog.dataich.com
# upload blog.dataich.com ssh://dotcloud@uploader.dotcloud.com:21122/wordpress
# rsync
Pseudo-terminal will not be allocated because stdin is not a terminal.
Warning: Permanently added '[uploader.dotcloud.com]:21122,[184.73.14.49]:21122' (RSA) to the list of known hosts.
building file list ... done
./
dotcloud.yml

sent 188 bytes  received 54 bytes  9.88 bytes/sec
total size is 52  speedup is 0.21
Deployment for "wordpress" triggered. Will be available in a few seconds.
2011-08-01 23:04:54 [api] Waiting for the build. (It may take a few minutes)
2011-08-01 23:04:54 [www.0] Deploying...
2011-08-01 23:04:54 [data.0] Deploying...
2011-08-01 23:05:25 [www.0] Service booted
2011-08-01 23:05:35 [data.0] Service booted
2011-08-01 23:05:35 [api] All the services are ready. Beginning the build.
2011-08-01 23:05:36 [data.0] The build started
2011-08-01 23:05:36 [data.0] This service type does not support build method, ignoring...
2011-08-01 23:05:36 [data.0] The build finished successfully
2011-08-01 23:05:36 [www.0] The build started
2011-08-01 23:05:36 [www.0] Fetched code revision rsync-1312214692.31
2011-08-01 23:05:37 [www.0] Updating channel "doc.php.net"
2011-08-01 23:05:37 [www.0] Update of Channel "doc.php.net" succeeded
2011-08-01 23:05:37 [www.0] Updating channel "pear.php.net"
2011-08-01 23:05:38 [www.0] Channel "pear.php.net" is up to date
2011-08-01 23:05:38 [www.0] Updating channel "pecl.php.net"
2011-08-01 23:05:38 [www.0] Update of Channel "pecl.php.net" succeeded
2011-08-01 23:05:38 [www.0] -su: line 0: cd: current: No such file or directory
2011-08-01 23:05:39 [www.0] -su: line 0: cd: current: No such file or directory
2011-08-01 23:05:39 [www.0] Reloading nginx configuration: nginx.
2011-08-01 23:05:42 [www.0] php5-fpm: stopped
2011-08-01 23:05:42 [www.0] php5-fpm: ERROR (abnormal termination)
2011-08-01 23:05:42 [www.0] The build finished successfully
2011-08-01 23:05:42 [api] Deploy finished

Deployment finished. Your application is available at the following URLs
www: http://xxxxxxxx.dotcloud.com/

最後の行にサービスwww(PHP)のURLが発行されているので、アクセスしてみます。当然何のリソースもPushしていないので、404が返ってくるかと思います。

データの移行

CORESERVERからとったデータベースダンプをdotCloud上のMySQLにロードします。そのためにdotCloudにデータベース、ユーザの作成をしておきます。

まずは、dotcloud infoでMySQLサービスの情報を取得します。ここでは書きませんが、rootパスワードその他情報が表示されるはずです。

dataich:dev dataich$ dotcloud info wordpress.data

次のコマンドでMySQLのシェルにログインします。

dataich:dev dataich$ dotcloud run wordpress.data -- mysql -u root -p
# mysql -u root -p
Warning: Permanently added '[xxxxxxxx.dotcloud.com]:12428,[174.129.17.131]:12428' (RSA) to the list of known hosts.
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 34
Server version: 5.1.41-3ubuntu12.10-log (Ubuntu)

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

mysql>

DBを作成します。

mysql> CREATE DATABASE wordpress;
Query OK, 1 row affected (0.00 sec)

ユーザを作成し、権限を与えます。

mysql> GRANT ALL ON wordpress.* TO 'dataich'@'%' IDENTIFIED BY 'XXXXXXXXXX';
Query OK, 0 rows affected (0.00 sec)

念のため

mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)

では、データをロードします。 データをアップし

dataich:dev dataich$ dotcloud run wordpress.data "cat > data.sql" < ~/Desktop/mysql_wp.dump # cat > data.sql
Pseudo-terminal will not be allocated because stdin is not a terminal.
Warning: Permanently added '[xxxxxxxx.dotcloud.com]:12428,[174.129.17.131]:12428' (RSA) to the list of known hosts.

SSHログインし

dataich:dev dataich$ dotcloud ssh wordpress.data
# $SHELL
Warning: Permanently added '[xxxxxxxx.dotcloud.com]:12428,[174.129.17.131]:12428' (RSA) to the list of known hosts.
mysql@wordpress-default-data-0:~$

ロードします。

mysql@wordpress-default-data-0:~$ mysql -u dataich -p wordpress < data.sql

WordPressソースの移行

アプリケーションのディレクトリにwwwというディレクトリを作り、そこにCORESEVERから持ってきたソースを置きます。

DBの設定を行うため、wp-config.phpを編集します。
dotcloudでは/home/dotcloud/environment.jsonに各種サービスの設定が書かれます。それを読むようにしてあげればOKです。

dataich:dev dataich$ vi blog.dataich.com/www/wp-config.php

nginxの設定

パーマリンク設定をp=123の形から変えている場合は、nginxの設定が必要になります。それにはnginx.confを置いてあげればOKです。

dataich:dev dataich$ vi blog.dataich.com/www/nginx.conf

wp-contentディレクトリの扱い

このままだと1回目以降にPushした際にwp-content以下が消えてしまいます。それではまずいので、すでにwp-contentディレクトリが存在する場合は何もしないようにpostinstallスクリプトを書いておきます。(dotcloudのヘルプそのまんま)

dataich:dev dataich$ vi blog.dataich.com/www/postinstall

dataich:dev dataich$ chmod +x blog.dataich.com/www/postinstall

dotCloudへWordpressソースをPush

これで、動くはず!さあ、Push!!!

dataich:dev dataich$ dotcloud push wordpress blog.dataich.com
# upload blog.dataich.com ssh://dotcloud@uploader.dotcloud.com:21122/wordpress
# rsync
Pseudo-terminal will not be allocated because stdin is not a terminal.
Warning: Permanently added '[uploader.dotcloud.com]:21122,[184.73.14.49]:21122' (RSA) to the list of known hosts.
building file list ... done
./
www/

..
..
..

www: http://xxxxxxxx.dotcloud.com/

上記、URLに正しくアクセスできました。

カスタムドメインの設定

まずはdotCloud側を設定します。aliasコマンドを使います。

dataich:~ dataich$ dotcloud alias add wordpress.www blog.dataich.com
Ok. Now please add the following DNS record:
blog.dataich.com. IN CNAME gateway.dotcloud.com.

CNAMEでgateway.dotcloud.com.を設定するように言われるので、VALUE-DOMAIN側のドメイン設定を行います。

http://blog.dataich.com/
上記にアクセスし、動作確認。無事上記ブログをdotCloudで動かすことに成功しました。
ざっと確認したところ問題なし。これで暫く運用テストしてみます。

ここまでやっといてアレなのですが、そう負荷のない個人ブログを運用するにはちょっとお値段が辛いです。
もう少しリーズナブルなプランがあればいいのですが。。

Facebooktwitterlinkedintumblrmail

PHP + SQLite で正規表現(PDO_SQLITE編) in CakePHP

CakePHP 1.3.6 での話です。

これ、やったのはずいぶんと前なんですが書いてなかったですね。
私はすごくうれしかったのですが、周りの反応は薄かった覚えがあります。

CakePHP 1.3 でSQLite3ってのはかなりイレギュラーで、確か、CakePHPのTracから探してきたドライバ(dbo_sqlite3.php)を使用しています。
確認しようと思ったのですがTracに繋がらないぞ?ってな状況。

そんなこんなでとてもマイナーな話なんですよね。 反応が薄いのもむべなるかな。

ですが、PDOでSQLiteにアクセスしている場合なら応用が効くかと思います。
dbo_sqlite3.php 内部でPDOが使用されておりますので。

app_model.php でやっているので関係するところをまとめて引用。

class AppModel extends Model {
    function beforeFind($queryData) {
        parent::beforeFind($queryData);
        //正規表現関数有効化
        $this->regxEnable();
    }

    /**
     * 正規表現関数有効化
     */
    public function regxEnable(){
        $db =& $this->getDataSource();
        $db->connection->sqliteCreateFunction('RGX', array('AppModel', 'sqliteRegexMatch'), 2);
    }

    /**
     * 正規表現関数
     */
    public function sqliteRegexMatch($regex, $str) {
        if(empty($regex)){
            return true;
        }else{
            return preg_match($regex, $str);
        }
    }
}

$db->connection がPDOのインスタンスです。
sqliteRegexMatch で $regex が empty の場合に true を返しているのは実装しているアプリケーションの都合ですのでご注意を。

実装の際、下記サイトを参考にさせていただきました。

SQLiteで正規表現 « karak

違いはPDOであること、preg_matchを使用していること、SQL関数を処理するコールバック関数としてメソッドを使っていることです。

CakePHP的ポイント

  • DBOからPDOのインスタンスを取得
  • beforeFindで検索時に正規表現関数を有効化

PDO_SQLITE的ポイント

  • sqliteCreateFunctionでSQL関数登録
  • sqliteCreateFunctionのコールバック関数にメソッドを登録する際の書式

使い方ですが、参考サイトと違ってpreg_matchでの正規表現であることに注意してくださいね。

私の場合、CakePHPでの使用ですので

    /**
     * モデルのconditonsに正規表現を使う場合の配列を返す。
     *
     * @param  $pattern 正規表現
     * @param  $cols 判定対象のカラムの配列
     * @return 
     */
    function whereByRgx($pattern, $cols) {
        $conditons = array();
        if(!empty($pattern)){
            foreach ($cols as $colname) {
                $conditons[] = "RGX('" . $pattern . "', " . $colname . ")";
            }
        }
        return $conditons;
    }

てなモデルでのfindなどで使用するconditions用の配列を返すメソッドを作って使っております。

Facebooktwitterlinkedintumblrmail

PHP5.1.6-27でのファイルアップロードと文字コード変換

OSはCentOS5.4でphp-5.1.6-27で確認しました。

この状態でencoding_translation = OnにしてFormタグにenctype=”multipart/form-data”を指定すると、同じForm内に入力した文字コードは自動変換されません。
encoding_translation = OffにしてPHPで全変換するか、事前にチェックして書き換えるか、悩みどころです。
encoding_translationの必要があるシステムは可能な限り避けたいなと思いますけどね。

Facebooktwitterlinkedintumblrmail