Hatena::ブログ(Diary)

ヌル日記

2011-12-17

[][][]FuelPHP動作実験 - oil consolePHP Interactive改を使って マニュアルの例文コピペでいろんなメソッドを試してみよう☆彡 03:48

皆様こんにちは! FuelPHP Advent Calendar 2011 17日目です。

昨日は @madmamor さんの 「FuelPHPのcoreクラスを拡張してみる。 」でした。

本日のお題は『oil consolePHP Interactive改を使って マニュアルの例文コピペでいろんなメソッドを試してみよう☆彡』です。

  1. oil console を使ってコマンドラインでFuelPHPのメソッドを呼び出してみる。
  2. PHP InteractiveからFuelPHPのメソッドを呼べるように微改造して、マニュアル例文コピペで色んなメソッドを試してみよう。

の開発・学習補助ネタ2本立てでいきます。

(ドキュメントの http://docs.fuelphp.com/packages/oil/console.html が今回該当する箇所になります。)

1. oil consoleって何よ?

FuelPHPのマニュアルを読んでいる最中、ちょっとだけコードの断片を試したい時、何かのコントローラーファイルに

<?php
(上略)
public function action_hogehoge()
{
  $arr1= Arr::average(array('1', 2, 4, '8'));
  var_dump($arr1);

  $arr2 = array('foo', 'bar', 'baz', 'yay');
  Debug::dump(Arr::to_assoc($arr2));

}
(下略)
?>

(Arr Class のお勉強中 - http://docs.fuelphp.com/classes/arr.html

みたいにソースをわざわざ書いてブラウザIDEで確認するのってカッタルイですよね。

FuelPHPにはそういう時用のconsole機能があり、コマンドラインから色々試すことができます。 ( http://docs.fuelphp.com/packages/oil/console.html)

oilコマンドはソースのREADME.md,fuel,docs,public等と同じ階層にあります。:

f:id:dix3:20111216175436p:image

---

php標準のdate()やdate_sunrise()なんてのを試してみたり、FuelPHPのArr::average()、Arr::to_assoc()を試してる図:

f:id:dix3:20111216181334p:image

FuelPHPを最初から呼び出せるphp -a みたいなものですね。

ただ、

<?php
  $arr1= Arr::average(array('1', 2, 4, '8'));
  var_dump($arr1);
  $arr2 = array('foo', 'bar', 'baz', 'yay');
  Debug::dump(Arr::to_assoc($arr2));
?>

の様な一行コードをマニュアルからコピペして試したい時にはまあ良いんですが、

<?php
$people = array(
  array(
    "name" => "Jack",
    "age" => 21
  ),
  array(
    "name" => "Jill",
    "age" => 23
  )
);
print_r( Arr::assoc_to_keyval($people, 'name', 'age') );
?>

みたいにコードに改行が入ってしまった場合うまく動きませんorz

うわぁあぁヽ(`Д´)ノキモイヨー :

f:id:dix3:20111216184908p:image


2. PHP InteractiveでFuelPHPのクラスを呼び出せるようにすればいいんじゃね?

で、このoilコマンドのconsole機能ですが一行毎にreadline()で入力を読み込んでevalしてるわけで複数行対応させるのは面倒。

そこで PHP Interactive - http://www.hping.org/phpinteractive/ の出番です。奥さん。

こいつは改行OKで複数行入力しながら、コードの断片をインタラクティブに動かして試せるスグレモノです。

こんな感じ:

f:id:dix3:20111216190623p:image

で、PHP InteractiveにFuelPHPのbootstrap.phpを読みこませればいいんじゃね?というわけで微改造してみました。以下その記録。

注意:これはフォーム内に書いたコードをevalして実行してるwebプログラムなので決して公開サーバーに設置しないでください。スパーハカーの餌食、遠隔リモコン君になってしまいます。あくまでも勉強用の外部から繋がらないローカル環境のみで実験してください。

PHP Interactive改でお勉強してるイメージ図:

f:id:dix3:20111217042141p:image:w520

高級なコーヒーでも飲みながら軽やかにサンプルコードをドラッグ・アンド・ドロップしてupdateボタン押して動作確認。

んで、コードが動いたらその場で少しずつオプションや値を変えたりしながら理解を深めていきます。なんてインテリジェンスなんでしょう!…

では微改造作業に着手しましょう。

以下ローカル環境。外からつながる鯖に決して設置しないこと。スパーハカーの餌食(以下略


作業1:PHP Interactiveのソースをダウンロードする。

ソースは ttp://www.hping.org/phpinteractive/phpinteractive-0.2.tar.gz より取得してください。(サイトは http://www.hping.org/phpinteractive/

作業2:ソースを解凍してpublic/phpinteractive以下に設置、パーミッションもchown,chmodで正しくしておく。

f:id:dix3:20111217014642p:image

(scripts以下は履歴保存ディレクトリなのでapacheユーザーの書き込み権限必須)


作業3:public/phpinteractive以下に.htaccessを新設

ソース: public/phpinteractive/.htaccess

php_flag short_open_tag On

phpinteractiveのソースがショートオープンタグを使っているのでこのディレクトリ配下のみshort_open_tagを有効にしています。

(サブディレクトリ.htaccessが使えない場合はapacheのconfファイルで AllowOverride Allになっているか要確認)


作業4:public/phpinteractive/includefuel.phpを新設

ソース: public/phpinteractive/includefuel.php

<?php
/**
 * Set error reporting and display errors settings.  You will want to change these when in production.
 */
error_reporting(-1);
ini_set('display_errors', 0);
/**
 * Website document root
 */
define('DOCROOT', dirname(dirname(__DIR__)).DIRECTORY_SEPARATOR);

/**
 * Path to the application directory.
 */
define('APPPATH', realpath(dirname(dirname(__DIR__)).'/fuel/app/').DIRECTORY_SEPARATOR);

/**
 * Path to the default packages directory.
 */
define('PKGPATH', realpath(dirname(dirname(__DIR__)).'/fuel/packages/').DIRECTORY_SEPARATOR);

/**
 * The path to the framework core.
 */
define('COREPATH', realpath(dirname(dirname(__DIR__)).'/fuel/core/').DIRECTORY_SEPARATOR);

// Get the start time and memory for use later
defined('FUEL_START_TIME') or define('FUEL_START_TIME', microtime(true));
defined('FUEL_START_MEM') or define('FUEL_START_MEM', memory_get_usage());

// bypass shutdown_handler
define('MY_INTERACTIVE_MODE', true);

// Boot the app
require APPPATH.'bootstrap.php';

//FUEL_ENV check
if('development'!==\Fuel::$env)
{
  echo 'development mode is required.';
  exit;
}
?>

oilを参考に作りました。MY_INTERACTIVE_MODE の定数は独自に追加しています。

うっかり本番の公開サーバーアップロードしてしまった時の気休めのため\Fuel::$envがdevelopment以外の時は何もせずここで終了させています。(参考 http://docs.fuelphp.com/installation/instructions.html#/setting_the_environment )


作業5:public/phpinteractive/index.phpを微修正

修正箇所は以下のとおりです。

変更箇所の画面ショット:

f:id:dix3:20111217021232p:image

オリジナルとの差分:

root@star:/var/vhosts/contact.pizw.net/public/phpinteractive# diff index.php orig_index.php
2d1
< include('./includefuel.php');
94c93
<       if(!@unlink("scripts/$name"))
---
>       if(!@unlink("scripts/$name"))
135c134
<               if (rename_script($current, $newname) == 0)
---
>               if (rename_script($current, $newname) == 0)
441,442c440
<    //echo(htmlentities($code))
<    echo(htmlentities($code, ENT_QUOTES, mb_internal_encoding()));
---
>    echo(htmlentities($code))
498,499c496
<       //$script_output = "<pre>".htmlentities($script_output)."</pre>";
<       $script_output = "<pre>".htmlentities($script_output, ENT_QUOTES, mb_internal_encoding())."</pre>";
---
>       $script_output = "<pre>".htmlentities($script_output)."</pre>";

2行目では新設したincludefuel.phpをincludeしています。これでFuelPHPのクラスが呼べるようになります。

441,498行目付近は日本語文字列を化けないようにする目的での修正です。


作業6:fuel/app/bootstrap.phpでError::のクラスを拡張出来るように変更

ソース: fuel/app/bootstrap.php

<?php

// Load in the Autoloader
require COREPATH.'classes'.DIRECTORY_SEPARATOR.'autoloader.php';
class_alias('Fuel\\Core\\Autoloader', 'Autoloader');

// Bootstrap the framework DO NOT edit this
require COREPATH.'bootstrap.php';


Autoloader::add_classes(array(
	// Add classes you want to override here
	// Example: 'View' => APPPATH.'classes/view.php',
	'Error' => APPPATH.'classes/error.php',//←この行を追加
));

// Register the autoloader
Autoloader::register();

/**
 * Your environment.  Can be set to any of the following:
 *
 * Fuel::DEVELOPMENT
 * Fuel::TEST
 * Fuel::STAGE
 * Fuel::PRODUCTION
 */
Fuel::$env = (isset($_SERVER['FUEL_ENV']) ? $_SERVER['FUEL_ENV'] : Fuel::DEVELOPMENT);

// Initialize the framework with the config file.
Fuel::init('config.php');

?>

PHP Interactiveの入力側でPHPの文法エラーになるような書き方をした場合、fuel/core/classes/error.phpのshutdown_handler()が反応し(fuel/core/bootstrap.php内のregister_shutdown_functionを参照)そこでexitしてしまうのですが、これではPHP Interactiveの画面も表示されなくなり、次の操作に困るため\Error::shutdown_handler()を微変更します。

こんな感じで止まると続行できなくて困るでよ:

f:id:dix3:20111217024638p:image:w520


作業7:fuel/app/classes/error.phpを新設

コアのクラスファイルを拡張します。(ドキュメント: http://docs.fuelphp.com/general/extending_core.html)

ソース: fuel/app/classes/error.php

<?php
/**
 * Core Class Extends Example (error.php)
 * @package
 * @version 0.01
 * @author mataga
 * @license MIT License
 * @copyright 2011 mataga
 * @link http://twitter.com/mataga
 */
class Error extends Fuel\Core\Error
{

  /**
   * Native PHP shutdown handler
   *
   * @return  string
   */
  public static function shutdown_handler()
  {
    $last_error = error_get_last();

    // Only show valid fatal errors
    if ($last_error AND in_array($last_error['type'], static::$fatal_levels))
    {
      $severity = static::$levels[$last_error['type']];
      logger(Fuel::L_ERROR, $severity.' - '.$last_error['message'].' in '.$last_error['file'].' on line '.$last_error['line']);

      $error = new \ErrorException($last_error['message'], $last_error['type'], 0, $last_error['file'], $last_error['line']);

      //MY_INTERACTIVDE_MODE -- ADD BEGIN
      if(defined('MY_INTERACTIVE_MODE') && MY_INTERACTIVE_MODE)
      {
        echo \Debug::dump($last_error);
        return;
      }
      //MY_INTERACTIVDE_MODE -- ADD END

      if (\Fuel::$env != Fuel::PRODUCTION)
      {
        static::show_php_error($error);
      }
      else
      {
        static::show_production_error($error);
      }

      exit(1);
    }
  }

}//endofclass
/* End of file error.php */
?>

//MY_INTERACTIVDE_MODE で挟んだ5行を追加しただけです。これでパースエラーが起きても PHP Interactive改経由の場合にはこんな感じで処理は続行されます。

f:id:dix3:20111217025623p:image:w520


作業8:動作確認

ttp://example.com/phpinteractive/ を開いていろいろ試すべし

こんな感じでArr::の実験をしてみたりすると、すぐに細かい動きを確認できて使い方を覚えるわけです。

f:id:dix3:20111217030248p:image



というわけでFuelPHPのドキュメントサイト( http://docs.fuelphp.com/ )のサンプルコードを動かしまくって、あなたも燃料テイスターになりませんか?

触れば触るほど深い味わいがしますぜ。


明日は @NEKOGET さんの「FuelPHPの呼び方。」になります。

ではでは!

icpa0icpa0 2012/04/06 16:26 はじめまして、ICPAの中原でございます。
突然のメールで失礼致します。ブログを拝見させて頂いてメールさせて頂いております。
私どもは外資系ヘッドハンティングファームでございます。外資系IT企業、コンサルティングファーム、国内IT企業のエンジニアポジションをご紹介しております。
現在、クライアント(自社サービスを持った企業)の強いご希望でスマートフォン向けアプリエンジニア、アプリケーションエンジニア、サーバー、DB周りのエンジニアを急務で探しておりまします。
管理人様が上記PHPでプログラミングが出来るエンジニアかと思い非常に興味を持っております。
もし、転職したい、作るプロダクトを変えたい、新しい技術を職場で学びたいという希望があれば、是非ご連絡ください。
何卒、よろしくお願いします。
E-mail nakahara@icpa.com

icpa0icpa0 2012/04/06 16:27 はじめまして、ICPAの中原でございます。
突然のメールで失礼致します。ブログを拝見させて頂いてメールさせて頂いております。
私どもは外資系ヘッドハンティングファームでございます。外資系IT企業、コンサルティングファーム、国内IT企業のエンジニアポジションをご紹介しております。
現在、クライアント(自社サービスを持った企業)の強いご希望でスマートフォン向けアプリエンジニア、アプリケーションエンジニア、サーバー、DB周りのエンジニアを急務で探しておりまします。
管理人様が上記PHPでプログラミングが出来るエンジニアかと思い非常に興味を持っております。
もし、転職したい、作るプロダクトを変えたい、新しい技術を職場で学びたいという希望があれば、是非ご連絡ください。
何卒、よろしくお願いします。
E-mail nakahara@icpa.com

icpa0icpa0 2012/04/06 16:30 間違えて2度同じ文章を投稿してしまいました。失礼致しました。

dix3dix3 2012/04/06 18:17 お誘いありがとうございます。
私自身も小さな会社の経営に携わっておりまして転職は現状できません。

将来の社員採用等でご縁がありましたらそのときはよろしくお願い申し上げます。

ヌル日記の内容は一切無保証です。個人的な作業履歴なので、実用では穴や間違いがあるかもしれません。

こちらの注意書きも一応読んでくださいね

Connection: close