[CakePHP]LIKE文のワイルドカードをエスケープする

Posted under CakePHP,php by uechoco on 木曜日 16 9月 2010 at 16 : 43 : 12

CakePHPでは等号(=)以外のSQL演算子を特殊な方法で指定します。たとえば、比較演算子であれば以下のような感じ。

php:
  1. $params['conditions']['User.created <'] = date('Y-m-d');

同様にLIKE文もこのように指定できます。

php:
  1. $params['conditions']['User.name LIKE'] = $this->data['User']['name'];

ここで困ったのがワイルドカードを使用する場合。検索文字列を%%でくくるなんていうことはよくあることですが、フォームに「%」を入れられてしまった場合、エスケープ処理をしないと全レコードが一致してしまい、検索結果が大変なことになります。

php:
  1. // エスケープ処理をしていないワイルドカード検索
  2. $params['conditions']['User.name LIKE'] = '%'.$this->data['User']['name'].'%';

LIKE文に指定する文字列は独自のエスケープ関数をAppModelに作成して呼び出すことにしましょう。なお、下記ソースコードはUTF-8での使用を想定しているので、そのほかの文字コードで記述する場合はstr_replace()の代わりにmb_ereg_replace()を使用することを検討してください。

php:
  1. class AppModel extends Model
  2. {
  3.     /**
  4.      * SQLのLIKE分のワイルドカードをエスケープする
  5.      *
  6.      * @params string $str LIKE文に指定する検索文字列
  7.      * @params boolean $before 検索文字列の前に % を付与するか
  8.      * @params boolean $after 検索文字列の後に % を付与するか
  9.      * @return string ワイルドカードがエスケープされたLIKE文
  10.      */
  11.     function escapeLikeSentence($str, $before = false, $after = false)
  12.     {
  13.         $result = str_replace('\\', '\\\\', $str); // \ -> \\
  14.         $result = str_replace('%', '\\%', $result); // % -> \%
  15.         $result = str_replace('_', '\\_', $result); // _ -> \_
  16.         return (($before) ? '%' : '').$result.(($after) ? '%' : '');
  17.     }
  18. }

モデル内での使用方法

php:
  1. // エスケープ処理をしたワイルドカード検索
  2. $like = $this->escapeLikeSentence($this->data['User']['name'], true, true);
  3. $params['conditions']['User.name LIKE'] = $like;

こういうエスケープ処理ってフレームワーク側でやってくれるものかと思ってたんですが、ワイルドカードで検索される可能性もあるから、勝手にエスケープはしないんですかね。


[ruby]Redmine 1.0.1をCentOS 5にインストール

Posted under ruby by uechoco on 木曜日 16 9月 2010 at 01 : 00 : 10

Wikiが欲しかったんですが、TracかRedmineみたいのがいいかなーと思って、Redmineのインストールに挑戦してみました。rubyは未開拓なのでいろいろ戸惑いました。

サーバ環境はServerman@VPSの256MBプランです。CentOS 5.4のi386です。root権限は使わずに、NOPASSWDのアカウントを仕様ています(基本的にsudoでインストール)。Apacheで、SQLite3での運用を考えています。redmineの本体は/var/work/redmineに設置しようかと思います。Apache httpdはyumか何かで既に入っている前提です。

Redmineは1.0.x系の最新の1.0.1を対象としています。Redmineのインストールガイド(Redmine - RedmineInstall - Redmine)を見ると、以下のような必要条件になっています。後述しますが、Rack 1.0.1というのはピンポイントでこのバージョンじゃないとデータベースのマイグレーションに失敗するようです。

  • Supported Ruby Version: ruby 1.8.6, 1.8.7
  • Required Rails version: Rails 2.3.5
  • Required Rack version: Rack 1.0.1

DL/解凍用の作業ディレクトリの作成

RPMやtar ballをダウンロードしたり、解凍するための場所として~/srcを使います。以下のインストール作業はこのディレクトリを使っていますので、適宜お好みのディレクトリに置き換えて読んでください。

Bash:
  1. # RPMやtar ballの置き場を作成
  2. mkdir ~/src

各種yumレポジトリのインストール

いくつかのレポジトリのためにyumのレポジトリをインストールします。私の好みで以下の3つをインストールします。使わないものもあるかもしれませんが。

  • Utter Ramblings
  • EPEL
  • RPMForge
Bash:
  1. # Utter RamblingsのGPGキーのインポート
  2. sudo rpm --import http://www.jasonlitka.com/media/RPM-GPG-KEY-jlitka
  3. # レポジトリ定義ファイルの作成
  4. sudo vim /etc/yum.repos.d/utterramblings.repo
  5. ### [utter]
  6. ### name=Jason’s Utter Ramblings Repo
  7. ### baseurl=http://www.jasonlitka.com/media/EL$releasever/$basearch/
  8. ### enabled=0
  9. ### gpgcheck=1
  10. ### gpgkey=http://www.jasonlitka.com/media/RPM-GPG-KEY-jlitka
  11.  
  12. # EPELレポジトリ追加
  13. sudo rpm -Uvh http://download.fedora.redhat.com/pub/epel/5/i386/epel-release-5-4.noarch.rpm
  14. # レポジトリ定義ファイルでenableを0にしておく
  15. sudo vim /etc/yum.repos.d/epel.repo
  16. ### enabled=0
  17.  
  18. # RPMForgeレポジトリ追加
  19. cd ~/src
  20. wget http://packages.sw.be/rpmforge-release/rpmforge-release-0.5.1-1.el5.rf.i386.rpm
  21. sudo rpm -ivh rpmforge-release-0.5.1-1.el5.rf.i386.rpm
  22. # レポジトリ定義ファイルでenableを0にしておく
  23. sudo vim /etc/yum.repos.d/rpmforge.repo
  24. ### enable=0

gcc、gcc-c++のインストール

Serverman@VPSにはgccが入っていませんでした。インストールします。

Bash:
  1. sudo yum -y install gcc gcc-c++

checkinstallのインストール

checkinstallはtar ballからRPMパッケージを作ってくれるツールです。ruby界隈では割とよく使われているようです。その流儀に従って、後述のrubyやsqliteはcheckinstallでRPMパッケージにしてからインストールします。RPMにしておけば、アンインストールも楽ですよね。

Bash:
  1. # rpm-buildってのが必要かも
  2. sudo yum -y install rpm-build
  3. # RPMForgeからcheckinstallをインストール
  4. sudo yum -y --enablerepo=rpmforge install checkinstall

rubyのインストール

CentOS 5のyumでインストール出来るrubyは1.8.5までです。最新のRedmineは1.8.6や1.8.7あたりでしか動作しないらしいので、tar ballでとってきて、checkinstallでRPM化して、インストールします。

Bash:
  1. # tar ballのダウンロード、解凍
  2. cd ~/src
  3. wget ftp://ftp.ruby-lang.org/pub/ruby/1.8/ruby-1.8.7-p302.tar.gz
  4. tar zxf ruby-1.8.7-p302.tar.gz
  5. # コンパイル
  6. cd ruby-1.8.7-p302
  7. ./configure --prefix=/usr
  8. make
  9. # RPM化
  10. sudo checkinstall --fstrans=no --exclude=/selinux
  11. # RPMでインストール
  12. sudo rpm -ivh /usr/src/redhat/RPMS/i386/ruby-1.8.7-p302-1.i386.rpm
  13.  
  14. # ruby バージョンの確認
  15. ruby --version

RubyGemsのインストール

RubyGemsはrubyの拡張を簡単にインストール出来る仕組みです。phpでいうPEAR/PECL、pythonでいうeasy_installみたいなものだと思います。さきほど、rubyの1.8.7を導入したので、RubyGemsは最新の1.3.7が入るはずです。

Bash:
  1. cd ~/src
  2. # 最新のRubyGemsをダウンロード
  3. wget http://rubyforge.org/frs/download.php/70696/rubygems-1.3.7.tgz
  4. tar zxf rubygems-1.3.7.tgz
  5. cd rubygems-1.3.7
  6. sudo ruby setup.rb
  7.  
  8. # gemのバージョンの確認
  9. gem --version

Ruby on Railsのインストール

いるかどうかわかりませんが、Ruby on Railsをインストールしておきます。いくつか警告のようなものが出てきますが、とりあえず無視しておきます。

Bash:
  1. sudo gem install rails
  2. rails --version

rack 1.0.1のインストール

どうやらRedmineでは、rack 1.0.1がないとデータベースのマイグレーションに失敗してしまうようです。ぴったりこのバージョンじゃないといけないようです。

Bash:
  1. sudo gem install rack -v=1.0.1

SQLite3のインストール

CentOS 5にはsqliteが既に入っているかもしれませんが、ややバージョンが古いです。今回はSQLite 3.6.16以上が必要なので、最新版をダウンロードしてcheckinstallでRPM化してインストールします。

Bash:
  1. cd ~/src
  2. # ダウンロード
  3. wget http://www.sqlite.org/sqlite-amalgamation-3.7.2.tar.gz
  4. tar zxf sqlite-amalgamation-3.7.2.tar.gz
  5. cd sqlite-3.7.2
  6. # コンパイルとRPM化、インストール
  7. ./configure --prefix=/usr
  8. sudo checkinstall --fstrans=no --exclude=/selinux
  9. sudo rpm -ivh  /usr/src/redhat/RPMS/i386/sqlite-3.7.2-1.i386.rpm
  10.  
  11. # バージョンを確認
  12. sqlite3 -version

sqlite3-rubyのインストール

sqlite3-rubyをインストールします。

Bash:
  1. sudo gem install sqlite3-ruby

redmineのインストール

ようやくRedmineのインストールに入ります。まずは本体をダウンロードし、運用ディレクトリに設置します。今回は/var/work/redmineに設置します。

Bash:
  1. cd ~/src
  2. # 最新の1.0.x系をダウンロード、解凍
  3. wget http://rubyforge.org/frs/download.php/72201/redmine-1.0.1.tar.gz
  4. tar zxf redmine-1.0.1.tar.gz
  5. # 運用ディレクトリに名前を変えて移動
  6. sudo mv redmine-1.0.1 /var/work/redmine
  7. # change directory
  8. cd /var/work/redmine
  9.  
  10. # DBの設定
  11. sudo vim config/database.yml
  12. ### production:
  13. ###  adapter: sqlite3
  14. ###  dbfile: db/redmine.db
  15. ###  timeout: 5000
  16.  
  17. # DBのマイグレートを行う(エラーが起きた)
  18. sudo rake db:migrate RAILS_ENV=production
  19. ### (in /var/work/redmine)
  20. ### rake aborted!
  21. ### A key is required to write a cookie containing the session data. Use config.action_controller.session = { :key => "_myapp_session", :secret => "some secret phrase" } in config/environment.rb
  22.  
  23. # エラーに従って設定を追記
  24. sudo vim config/environment.rb
  25. ###  config.action_controller.session = { :key => "_myapp_session", :secret => "SKv83bVAs39cjh" }
  26.  
  27. # DBのマイグレートを行う(再挑戦、またエラーが起きた)
  28. sudo rake db:migrate RAILS_ENV=production
  29. ### (in /var/work/redmine)
  30. ### rake aborted!
  31. ### Secret should be something secure, like "77fb77e9ba061d6236016ca6cf9d3f87".  The value you provided, "SKv83bVAs39cjh", is shorter than the minimum length of 30 charsudoacters
  32.  
  33. # エラーに従ってセッションキーを30文字以上の文字に変更
  34. sudo vim config/environment.rb
  35. ### config.action_controller.session = { :key => "_myapp_session", :secret => "kljdvh0hljsbav753wrbkCA87sdSb87qbvhjkVCABrqc98bAiu" }
  36.  
  37. # DBのマイグレートを行う(再挑戦、変なログがたくさん流れて終わった)
  38. sudo rake db:migrate RAILS_ENV=production
  39.  
  40. # 初期データのロード
  41. sudo rake redmine:load_default_data RAILS_ENV=production
  42. ### 「Select language」と出てきたら「ja」と入力

Passenderのインストール

PassengerというApacheのモジュールを導入します。これによってrubyがapacheで効率的に動作するようになります。

Bash:
  1. # install Passenger Web サーバ
  2. sudo gem install passenger
  3.  
  4. # インストールされた関連ファイルの確認
  5. ls -la /usr/bin/passenger*
  6. ### -rwxr-xr-x 1 root root 391 Sep  7 23:14 /usr/bin/passenger-config
  7. ### -rwxr-xr-x 1 root root 407 Sep  7 23:14 /usr/bin/passenger-install-apache2-module
  8. ### -rwxr-xr-x 1 root root 405 Sep  7 23:14 /usr/bin/passenger-install-nginx-module
  9. ### -rwxr-xr-x 1 root root 401 Sep  7 23:14 /usr/bin/passenger-make-enterprisey
  10. ### -rwxr-xr-x 1 root root 397 Sep  7 23:14 /usr/bin/passenger-memory-stats
  11. ### -rwxr-xr-x 1 root root 397 Sep  7 23:14 /usr/bin/passenger-spawn-server
  12. ### -rwxr-xr-x 1 root root 391 Sep  7 23:14 /usr/bin/passenger-status
  13. ### -rwxr-xr-x 1 root root 396 Sep  7 23:14 /usr/bin/passenger-stress-test
  14.  
  15. # Apache用モジュールのビルドとインストール(サジェスチョンが表示される、バージョンが違うかもしれないので表示されたものを使用してください)
  16. sudo passenger-install-apache2-module
  17. ### Please edit your Apache configuration file, and add these lines:
  18. ###
  19. ###    LoadModule passenger_module /usr/lib/ruby/gems/1.8/gems/passenger-2.2.15/ext/apache2/mod_passenger.so
  20. ###    PassengerRoot /usr/lib/ruby/gems/1.8/gems/passenger-2.2.15
  21. ###    PassengerRuby /usr/bin/ruby
  22. ###
  23. ### Suppose you have a Rails application in /somewhere. Add a virtual host to your
  24. ### Apache configuration file and set its DocumentRoot to /somewhere/public:
  25. ###
  26. ### <VirtualHost *:80>
  27. ###    ServerName www.yourhost.com
  28. ###    DocumentRoot /somewhere/public    # <-- be sure to point to 'public'!
  29. ###    <Directory /somewhere/public>
  30. ###       AllowOverride all              # <-- relax Apache security settings
  31. ###       Options -MultiViews            # <-- MultiViews must be turned off
  32. ###    </Directory>
  33. ### </VirtualHost>
  34.  
  35. # Apahceの各種設定
  36. sudo vim /etc/httpd/conf.d/passenger.conf
  37. ### LoadModule passenger_module /usr/lib/ruby/gems/1.8/gems/passenger-2.2.15/ext/apache2/mod_passenger.so
  38. ### PassengerRoot /usr/lib/ruby/gems/1.8/gems/passenger-2.2.15
  39. ### PassengerRuby /usr/bin/ruby
  40. sudo vim /etc/httpd/conf/httpd.conf
  41. ### NameVirtualHost *:80
  42. sudo vim /etc/httpd/conf.d/vhost.conf
  43. ### <VirtualHost *:80>
  44. ###   ServerName redmine.example.com
  45. ###   DocumentRoot /var/work/redmine/public
  46. ###   <Directory /var/work/redmine/public>
  47. ###     AllowOverride all
  48. ###     Options -MultiViews
  49. ###   </Directory>
  50. ###   ErrorLog logs/redmine.example.com_error_log
  51. ###   CustomLog logs/redmine.example.com_access_log combined
  52. ### </VirtualHost>
  53.  
  54. # Apacheの再起動
  55. sudo apachectl -t
  56. sudo apachectl graceful

Internal Server Errorとの格闘

インストールに慣れていないせいか、Internal Server Errorと戦うことになりました。

Bash:
  1. # この時点で試しにredmine.example.comにアクセスすると、Internal Server Errorとなる。
  2.  
  3. # パーミッションの設定を忘れていた
  4. sudo chown -R apache:apache ./*
  5. sudo mkdir tmp public/plugin_assets
  6. sudo chmod -R 777 files log tmp public/plugin_assets/
  7. sudo chmod 666 db/redmine.db
  8. sudo apachectl graceful
  9.  
  10. # この時点で試しにredmine.example.comにアクセスすると、Internal Server Errorとなる。
  11.  
  12. # Railsのバージョンを適切なバージョンを入れてみる
  13. sudo gem install rails -v=2.3.5
  14. sudo apachectl graceful
  15.  
  16. # この時点で試しにredmine.example.comにアクセスすると、Internal Server Errorとなる。
  17.  
  18. # Apacheのerror_logをみて1つずつ改善していくことにする。
  19. # [1]: /var/work/redmine/vendor/rails/railties/lib/rails/gem_dependency.rb:119:Warning: Gem::Dependency#version_requirements is deprecated and will be removed on or after August 2010.  Use #requirement
  20. # 参考リンク:
  21. # > http://pinzolog.blogspot.com/2010/07/versionrequirements-is-deprecated.html
  22. # > http://d.hatena.ne.jp/tkrd/20100328/1269738099
  23. sudo vim config/environment.rb
  24. sudo apachectl graceful
  25.  
  26. # [2]: The {{key}} interpolation syntax in I18n messages is deprecated. Please use %{key} instead.
  27. # 参考リンク:
  28. # > http://shockby.com/2010/08/14/redmine%E3%81%A7i18%E9%96%A2%E9%80%A3%E3%81%A7%E3%82%A8%E3%83%A9%E3%83%BC%E3%81%8C%E5%87%BA%E3%81%9F/
  29. # > http://www.redmine.org/issues/6314
  30. sudo gem install i18n -v=0.3.7
  31. sudo apachectl graceful
  32.  
  33. # この時点で試しにredmine.example.comにアクセスすると、最初のページはアクセス可能だが、マイページはInternal Server Errorとなる。
  34. # 不要なバージョンを消してみる
  35. sudo gem uninstall rails -v=3.0.0
  36. sudo gem uninstall actionmailer -v=3.0.0
  37. sudo gem uninstall railties -v=3.0.0
  38. sudo gem uninstall actionpack -v=3.0.0
  39. sudo gem uninstall activerecord -v=3.0.0
  40. sudo gem uninstall activeresource -v=3.0.0
  41. sudo gem uninstall activemodel -v=3.0.0
  42. sudo gem uninstall i18n -v=0.4.1
  43. sudo apachectl graceful
  44.  
  45. # 無事に表示される

どうやら今のところ、正常に動いています。

教訓:バージョン指定があるものは、ピンポイントでそのバージョンを入れるべき。


[xampp][php]sendmailを使用する

Posted under php by uechoco on 火曜日 14 9月 2010 at 21 : 31 : 38

xamppのローカルのphpからメールを送るには、xamppの内部のsendmail.exeの設定をするだけで可能です。以下のサイトの通りにやればできました。

参考:Xampp sendmail の設定 | モデルさんのお金

なお、私はyahooのSMTPサーバを利用してsendmailを使うことにしましたが、Yahooメールの「POPアクセスとメール転送」を使用する設定でないと、認証に失敗します。sendmail.logに「smtpstatus=535 smtpmsg='535 authorization failed (#5.7.0)' errormsg='authentication failed (method PLAIN)' exitcode=EX_NOPERM」が残ると思います。


[php](断念)Unable to initialize module\nModule compiled with module API

Posted under php by uechoco on 火曜日 14 9月 2010 at 09 : 07 : 33

Apacheのerror_logに以下のようなのがでます。

PHP Warning: PHP Startup: readline: Unable to initialize module\nModule compiled with module API=20050922, debug=0, thread-safety=0\nPHP compiled with module API=20060613, debug=0, thread-safety=0\nThese options need to match\n in Unknown on line 0

Utter Rambringsレポジトリを使ってyumでphp 5.2.13が入っている環境なのですが、yum list php*すると、以下のようになります。php-readlineだけ他と比べてバージョンが低いです。

Bash:
  1. # yum パッケージの削除
  2. sudo yum remove php-readline
  3. # 適当なディレクトリにphp 5.2.13のDL、解凍
  4. cd ~/src
  5. wget http://jp2.php.net/get/php-5.2.13.tar.gz/from/this/mirror
  6. tar zxf php-5.2.13.tar.gz
  7. # readline拡張をphpizeでインストール(撃沈)
  8. cd php-5.2.13/ext/readline/
  9. phpize
  10. ./configure
  11. # configure: error: Please reinstall libedit - I cannot find readline.h

configure: error: Please reinstall libedit - I cannot find readline.h

Bash:
  1. # libeditとlibedit-develをEPELレポジトリからインストール
  2. sudo yum -y --enablerepo=epel install libedit libedit-devel
  3.  
  4. # 再度readline拡張をインストール(撃沈)
  5. ./configure
  6. make
  7. # make: *** [readline.lo] Error 1

'rl_mark' undeclared (first use in this function)

コンパイルエラーの内容はこんな感じ。

TEXT:
  1. [admin@localhost]$ make
  2. /bin/sh /home/admin/src/php-5.2.13/ext/readline/libtool --mode=compile cc  -I. -I/home/admin/src/php-5.2.13/ext/readline -DPHP_ATOM_INC -I/home/admin/src/php-5.2.13/ext/readline/include -I/home/admin/src/php-5.2.13/ext/readline/main -I/home/admin/src/php-5.2.13/ext/readline -I/usr/include/php -I/usr/include/php/main -I/usr/include/php/TSRM -I/usr/include/php/Zend -I/usr/include/php/ext -I/usr/include/php/ext/date/lib  -DHAVE_CONFIG_H  -g -O2   -c /home/admin/src/php-5.2.13/ext/readline/readline.c -o readline.lo
  3.  cc -I. -I/home/admin/src/php-5.2.13/ext/readline -DPHP_ATOM_INC -I/home/admin/src/php-5.2.13/ext/readline/include -I/home/admin/src/php-5.2.13/ext/readline/main -I/home/admin/src/php-5.2.13/ext/readline -I/usr/include/php -I/usr/include/php/main -I/usr/include/php/TSRM -I/usr/include/php/Zend -I/usr/include/php/ext -I/usr/include/php/ext/date/lib -DHAVE_CONFIG_H -g -O2 -c /home/admin/src/php-5.2.13/ext/readline/readline.c  -fPIC -DPIC -o .libs/readline.o
  4. /home/admin/src/php-5.2.13/ext/readline/readline.c: In function 'zif_readline_info':
  5. /home/admin/src/php-5.2.13/ext/readline/readline.c:184: error: 'rl_mark' undeclared (first use in this function)
  6. /home/admin/src/php-5.2.13/ext/readline/readline.c:184: error: (Each undeclared identifier is reported only once
  7. /home/admin/src/php-5.2.13/ext/readline/readline.c:184: error: for each function it appears in.)
  8. /home/admin/src/php-5.2.13/ext/readline/readline.c:185: error: 'rl_done' undeclared (first use in this function)
  9. /home/admin/src/php-5.2.13/ext/readline/readline.c:186: error: 'rl_pending_input' undeclared (first use in this function)
  10. make: *** [readline.lo] Error 1

readline系の関数がないのかと推測して、readline-develパッケージをインストールして再挑戦してみます。

Bash:
  1. # readline-develをインストール
  2. sudo yum -y install readline-devel
  3.  
  4. # 再再度readline拡張をインストール(撃沈)
  5. ./configure
  6. make
  7. # make: *** [readline.lo] Error 1

関係有りませんでした。

久しぶりに私の能力では解決できそうもないので、そしてreadlineはUnix系でしか使えないので別にいいかなって思って諦めました。なんだったんだろう。。。


[DB]MyISAMからInnoDBへ変換

Posted under Webプログラミング by uechoco on 金曜日 10 9月 2010 at 18 : 37 : 02

phpMyAdminにも同じ機能がありますが、実際はこんなSQLを発行することでMyISAMからInnoDBへ変換できます。

SQL:
  1. ALTER TABLE  `users` ENGINE = InnoDB;


次ページへ »

Copyright © 2012 うえちょこ@ぼろぐ. WP Theme created by Web Top.