ダミー画像を動的に作るPHPスクリプトを作ってみた

こいつは便利!好きなサイズのダミー画像が動的に作れる『Dummy Image』 – IDEA*IDEA ~ 百式管理人のライフハックブログで紹介されているDynamic Dummy Image Generatorが便利そうだけど、ネットに繋がってないときは使えないんで、PHPで自作してみた。

dummyimage.zip

GDが使える環境なら動作すると思います。
使い方は
http://localhost/dummyimage.php?size=200×100&alpha=50&format=png
みたいに指定します。1ファイルで済ましてるんでDynamic Dummy Image GeneratorよりURLが長いです。
で、こういうのが生成されます。(少し濃い色の枠はWordPressのテーマが勝手につけてるだけです)

sizeのみ必須です。size=200×100は幅200px高さ100pxの画像を生成します。size=100だと100pxの正方形になります。
alphaは0から100を指定。0が不透明。100が完全透過。
formatはpngかjpegを指定。大文字も可。

デバッグ十分でないのでバグ報告よろしくです。

Snow LeopardにMacPortsでApache+MySQL+PHPのWebアプリケーション開発環境を作成する

MacPortsでApache+MySQL+PHPをインストールしてWebアプリケーション開発環境を作成します。

Mac OS X 10.6 Snow LeopardにMacPortsとDeveloperToolsをインストールしていることを前提にしています。

Apacheのインストールと設定

MacPortsでApacheをインストールします。

$ sudo port install apache2


インストールの最後に以下の文が表示されます。

###########################################################
# A startup item has been generated that will aid in
# starting apache2 with launchd. It is disabled
# by default. Execute the following command to start it,
# and to cause it to launch at startup:
#
# sudo launchctl load -w /Library/LaunchDaemons/org.macports.apache2.plist
###########################################################

Apacheはlaunchdで開始するようになっています。デフォルトでは無効になっているので、sudo launchctl load -w /Library/LaunchDaemons/org.macports.apache2.plistを実行して有効にします。有効にするとApacheが起動します。また、OSを再起動してもApacheが自動的に起動されるようになります。

Apacheの動作確認のため、ブラウザでlocalhostもしくはシステム環境設定の共有で指定したコンピュータ名.localにアクセスします。正しく動作していれば「It works!」と表示されます。

開発環境なので、Apacheのドキュメントルートを~/Sitesフォルダに、実行ユーザを自分のユーザアカウントに変更します(ルートを変更せずに#Include conf/extra/httpd-userdir.confの#を削って有効にすれば、ユーザごとにSitesフォルダが使用できるようになります。)。さらに、機能や設定を自由に変更できるようにします。

/opt/local/apache2/conf/httpd.confファイルの
User wwwをUser yourusername
DocumentRoot “/opt/local/apache2/htdocs”をDocumentRoot “/Users/yourusername/Sites”

<Directory “/opt/local/apache2/htdocs”>を<Directory “/Users/yourusername/Sites”>

(上記Directory内の)Options Indexes FollowSymLinksをOptions All、AllowOverride NoneをAllowOverride All

に変更します。

これらの変更を以下のコマンドでApacheに適用します。

$ sudo /opt/local/apache2/bin/apachectl graceful


再度localhostにアクセスすると、/Users/yourusername/Sitesが表示されます。

MySQLのインストールと設定

続いてMySQLをインストールします。

$ sudo port install mysql5-server

起動する前にデータベースの設定をしておきます。my.cnfを設置して編集します。

$ sudo cp /opt/local/share/mysql5/mysql/my-medium.cnf /opt/local/etc/mysql5/my.cnf


[client]
default-character-set=utf8
[mysqld]
datadir=/Users/yourusername/local/var/mysql
language=/opt/local/share/mysql5/mysql/japanese
default-character-set=utf8
skip-character-set-client-handshake
[mysqldump]
default-character-set=utf8
[mysql]
default-character-set=utf8

MacPortsでインストールしたときに以下の文が表示されます。

###########################################################
# A startup item has been generated that will aid in
# starting mysql5-server with launchd. It is disabled
# by default. Execute the following command to start it,
# and to cause it to launch at startup:
#
# sudo launchctl load -w /Library/LaunchDaemons/org.macports.mysql5.plist
###########################################################
******************************************************
* In order to setup the database, you might want to run
* sudo -u mysql mysql_install_db5
* if this is a new install
******************************************************

これまでMySQLをインストールしたことがない場合はsudo -u mysql mysql_install_db5を実行します。sudo launchctl load -w /Library/LaunchDaemons/org.macports.mysql5.plistを実行して起動します。mysql5を実行するかSequel ProでMySQLサーバに接続して、動作しているか確認します。ソケットは/opt/local/var/run/mysql5/mysqld.sockです。

PHPのインストールと設定

PHP5.2系をインストールします。以下の設定が可能です。

$ port variants php52
php52 has the variants:
   apache: Add Apache 1 web server module
     * conflicts with apache2 no_web
[+]apache2: Add Apache 2.2 web server module
     * conflicts with apache no_web
   darwin_10: Platform variant, selected automatically
   dbase: Add dBase file format support
   debug: Enable debug support (useful to analyze a PHP-related core dump)
   fastcgi: Add FastCGI web server binary
     * conflicts with no_web
   gmp: Add GNU MP multiprocessing functions
   imap: Add IMAP protocol support
   ipc: Add semaphore, shared memory and IPC functions
   macosx: Platform variant, selected automatically
   macports_snmp: Add SNMP support using MacPorts SNMP
     * conflicts with snmp
   mssql: Add MS-SQL server support
   mysql4: Add MySQL 4 support
     * conflicts with mysql5
   mysql5: Add MySQL 5 support
     * conflicts with mysql4
   no_web: Don't include any web server support
     * conflicts with apache apache2 fastcgi
   oracle: Add Oracle oci8 database functions with the Oracle Instant Client
   pcntl: Add process control functions
   pear: Add PEAR
   postgresql82: Add postgresql82 support
     * conflicts with postgresql83
   postgresql83: Add postgresql83 support
     * conflicts with postgresql82
   pspell: Add pspell spell-checking functions
   readline: Add GNU readline functions
   snmp: Add SNMP support using Apple SNMP
     * conflicts with macports_snmp
   sockets: Add socket communication functions
   sqlite: Add SQLite support
   suhosin: Add Suhosin patch
   t1lib: Add PostScript Type 1 font support with t1lib
   tidy: Add Tidy support
   universal: Build for multiple architectures


とりあえずApache2 / MySQL / PEARを指定しますが、たとえばSQLiteのサポートが必要であれば+sqliteを指定したり、必要なものを指定します。また、PHP 5.3系を利用する場合はphp52ではなくphp5ポートを利用し、+mysqlではなくphp5-mysqlポートをインストールします。

$ sudo port install php52 +apache2+mysql5+pear
To customize php, copy
/opt/local/etc/php5/php.ini-dist (if this is a development server) or
/opt/local/etc/php5/php.ini-recommended (if this is a production server) to
/opt/local/etc/php5/php.ini and then make changes.
 
If this is your first install, you need to activate PHP in your web server.
 
To enable PHP in Apache, run
  cd /opt/local/apache2/modules
  /opt/local/apache2/bin/apxs -a -e -n "php5" libphp5.so

指示通りにPHP設定ファイルを配置して、PHPをApacheに組み込みます。

$ sudo cp /opt/local/etc/php5/php.ini-dist /opt/local/etc/php5/php.ini
$ sudo /opt/local/apache2/bin/apxs -a -e -n "php5" libphp5.so

/opt/local/apache/conf/httpd.confを編集します。
DirectoryIndexにindex.phpを追加します。

<IfModule dir_module>
    DirectoryIndex index.html index.php
</IfModule>


httpd.confの最後に以下を追加します。

Include conf/extra/mod_php.conf

Apacheに設定を反映させます。

$ sudo /opt/local/apache2/bin/apachectl graceful

PHPの動作をテストするために、~/Sites/info.phpファイルを以下の内容で作成します。

<?php phpinfo(); ?>


http://localhost/info.phpにアクセスして、PHPの動作を確認します。PHPの情報が表示されればインストール成功です。

Cucumber+WebratでPHPアプリのテストをする

sudo gem install cucumber mechanize rspec webratPHP – cucumber – GitHub

を参考にCucumberでPHPアプリケーションの受け入れテストを作成・実行してみます。さらにこのチュートリアルでは日本語でテストを記述してみます。

Cucumberのインストール

Ruby 1.9.1をすでにインストールしてある環境です。まずはCucumber・Webrat・mechanize・rspecをインストールします。

$ sudo sudo gem install cucumber mechanize rspec webrat

ディレクトリの作成

テストするPHPアプリのトップディレクトリに以下のディレクトリを作成します。

features
features/support
features/step_definitions

環境設定ファイルの作成

features/support/env.rbを以下の内容で作成します。RSpecやWebratを読み込んで、各種設定を行っています。Seleniumを利用するといった場合はこのファイルを編集して設定を変更します。

# RSpec
require 'spec/expectations'
 
# Webrat
require 'webrat'
 
require 'test/unit/assertions'
World(Test::Unit::Assertions)
 
Webrat.configure do |config|
  config.mode = :mechanize
end
 
World do
  session = Webrat::Session.new
  session.extend(Webrat::Methods)
  session.extend(Webrat::Matchers)
  session
end

Cucumberのコマンドライン引数の設定

Cucumberのコマンドライン引数のデフォルトを設定するために以下の内容でルートディレクトリにcucumber.ymlを作成します。–language jaを指定することで日本語でテストを記述できるようになります。以下のdefaultではコマンドラインに結果が出力されますが、結果をHTMLで出力する設定を記述しておき、テスト実行時に適宜設定を指定することができます。

default: --language ja features

ステップの作成

features/step_definitionsディレクトリにwebrat_steps.rbとresult_steps.rbの2つのテストステップファイルを作成します。

features/step_definitions/webrat_steps.rb
Webratでページにアクセスしたりボタンをクリックしたりできるステップを作成します。

# -*- encoding: UTF-8 -*-
 
前提 /^(.*)ページを表示している$/ do |path|
  @response = visit "http://localhost/php_with_cucumber#{path}"
end
 
もし /^(.*)ページを表示する$/ do |path|
  @response = visit "http://localhost/php_with_cucumber#{path}"
end
 
もし /^"(.*)"ボタンをクリックする$/ do |button|
  @response = click_button(button)
end
 
もし /^"(.*)"リンクをクリックする$/ do |link|
  @response = click_link(link)
end
 
もし /^"(.*)""(.*)"と入力する$/ do |field, value|
  @response = fill_in(field, :with => value) 
end
 
もし /^"(.*)"から"(.*)"を選択する$/ do |field, value|
  @response = select(value, :from => field) 
end
 
もし /^"(.*)"をチェックする$/ do |field|
  @response = check(field) 
end
 
もし /^"(.*)"のチェックを外す$/ do |field|
  @response = uncheck(field) 
end
 
もし /^"(.*)"を選択する$/ do |field|
  @response = choose(field)
end
 
もし /^パスが"(.*)"のファイルを"(.*)"に添付する $/ do |path, field|
  @response = attach_file(field, path)
end

ページの表示ではhttp://localhost/php_with_cucumberを直に書き込んで、テストを記述するfeatureファイルではアドレスを省略できるようにしています。

features/step_definitions/result_steps.rb
結果の検査を行うステップを作成します。

# -*- encoding: UTF-8 -*-
 
ならば /^"(.*)"と表示される$/ do |text|
  response_body.to_s.force_encoding("UTF-8").should =~ /#{text}/m
end
 
ならば /^"(.*)"と表示されない$/ do |text|
  response_body.to_s.force_encoding("UTF-8").should_not =~ /#{text}/m
end
 
ならば /^(\w+)メッセージが表示さる$/ do |message_type|
  @response.should have_xpath("//*[@class='#{message_type}']")
end
 
ならば /^(.*)リクエストが失敗する/ do |_|
  @response.should_not be_successful
end
 
ならば /ページ読み込みが成功する/ do
  @response.code.should == "200"
end

今回のテストでは使用しないステップも含まれています。実際に動作するか検証してませんが、こんな感じで作成するということで参考にしてください。

テスト対象のコード

実際にはテストを記述してコードを作成していくかもしれませんが、今回はすでに作成した以下のPHPコードをindex.phpとして保存してテストしてみます。機能はテキストエリアにテキストを入力してSubmitをクリックすると、入力したテキストが表示されるというものです。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja">
 
<head>
    <title>PHP with Cucumber</title>
</head>
<body>
    <h1>PHP with Cucumber</h1>
 
    <?php if(!isset($_GET['text']) or empty($_GET['text'])) print '<p>テキストを入力してください。</p>'; ?>
 
    <form action="/php_with_cucumber/index.php" method="get">
        <p><textarea name="text" rows="10" cols="100"></textarea></p>
        <p><input type="submit" value="Submit" /></p>
    </form>
 
    <p class="printed_text"><?php if(isset($_GET['text'])) print $_GET['text']; ?></p>
 
    <p><a href="./">リセット</a></p>
</body>
</html>

テストの作成

テストを作成します。featuresディレクトリにshow.featureファイルを作成します。ページの表示・結果の表示・表示のリセットをテストします。

機能: トップページの表示とサブミット
 
  シナリオ: トップページの表示
    もし /ページを表示する
    ならば ""と表示される
    かつ "テキストを入力してください。"と表示される
 
  シナリオ: テキストの入力と結果の表示してリセットする
    前提 /ページを表示している
    もし "text"に"テスト用のテキストです。"と入力する
    かつ "submit"ボタンをクリックする
    ならば "テスト用のテキストです。"と表示される
    かつ "テキストを入力してください。"と表示されない
    もし "リセット"リンクをクリックする
    ならば "テキストを入力してください。"と表示される

もっと機能があれば機能ごとにファイルを分割します。またこの例では、テスト内容は不十分ですので、ステップやシナリオを追加して試してみてください。

テストの実行

ではテストを実行してみます。コマンドラインでルートディレクトリに移動してcucumberを実行します。

$ cucumber
Using the default profile...
機能: トップページの表示とサブミット
 
  シナリオ: トップページの表示                                # features/show.feature:3
    もし /ページを表示する                                 # features/step_definitions/webrat_steps.rb:7
    ならば ""と表示される # features/step_definitions/result_steps.rb:3
    かつ "テキストを入力してください。"と表示される                    # features/step_definitions/result_steps.rb:3
 
  シナリオ: テキストの入力と結果の表示してリセットする     # features/show.feature:8
    前提 /ページを表示している                # features/step_definitions/webrat_steps.rb:3
    もし "text"に"テスト用のテキストです。"と入力する # features/step_definitions/webrat_steps.rb:19
    かつ "submit"ボタンをクリックする         # features/step_definitions/webrat_steps.rb:11
    ならば "テスト用のテキストです。"と表示される      # features/step_definitions/result_steps.rb:3
    かつ "テキストを入力してください。"と表示されない    # features/step_definitions/result_steps.rb:7
    もし "リセット"リンクをクリックする           # features/step_definitions/webrat_steps.rb:15
    ならば ページ読み込みが成功する              # features/step_definitions/result_steps.rb:19
    かつ "テキストを入力してください。"と表示される     # features/step_definitions/result_steps.rb:3
 
2 scenarios (2 passed)
11 steps (11 passed)
0m0.029s

すべてのシナリオがパスしました。ここで、たとえば「ならば “テスト用のテキストです。”と表示される」を「ならば “テストのテキストです。”と表示される」に変更してCucumberを実行してみると、11 steps (1 failed, 4 skipped, 6 passed)となります。コマンドラインではカラーで表示されるので、真っ赤な画面だったらfailedで、緑だったらpassedです。

おまけ

作成したファイルの書庫: php_with_cucumber.zip

最終的なディレクトリ・ファイル構成

.
|-- cucumber.yml
|-- features
|   |-- show.feature
|   |-- step_definitions
|   |   |-- result_steps.rb
|   |   `-- webrat_steps.rb
|   `-- support
|       `-- env.rb
`-- index.php