2010年2月22日

Zend_Controller_Router_Route_Regexで正規表現によるルーティング設定を行う

カテゴリー: ZendFramework — admin @ 1:35 AM

以下のように、Zend_Controller_Router_Route_Regexを使用する。

$front->getRouter()->addRoute(
	'page',
	new Zend_Controller_Router_Route_Regex(
		'page_(\d+)\.html',
		array(
			'controller' => 'Index',
			'action'     => 'page'
		),
		array(
			1 => 'pageid'
		)
	)
);

Actionからは以下のコードでマッチした部分を参照できる。

$this->_getParam('pageid');

2010年2月22日

PHPからドメインを取得する

カテゴリー: PHP — admin @ 12:18 AM

var_dump($_SERVER['SERVER_NAME']);
//string(16) "sample.org"

マルチドメイン、シングルホスティングの時には使いそうだ。

2010年2月14日

ZendFrameworkでコマンドラインからアクションを実行する

カテゴリー: PHP, ZendFramework — admin @ 11:56 PM

コマンドラインにおけるオプションの設定・取得。|の後がエイリアス名、=の後の文字列で型を指定できる。

try {
    $options = new Zend_Console_Getopt(
        array(
            'help|h'        => 'help.',
            'zfm|m=s'       => 'module',
            'zfc|c=s'       => 'controller',
            'zfa|a=s'       => 'action'
        )
    );
    $options->parse();
}
catch(Zend_Console_Getopt_Exception $e){
    die($e->getMessage() . ' : ' . $e->getUsageMessage());
}

Zend_Controller_Request_Simpleがポイント。アクション、コントローラ、モジュールを引数に指定してリクエストオブジェクトを取得する。

if(isset($options->zfa) && isset($options->zfc) && isset($options->zfm)){
    $request = new Zend_Controller_Request_Simple(
        $options->zfa,
        $options->zfc,
        $options->zfm
    );
    $front = Zend_Controller_Front::getInstance();
    $front->setRequest($request);
    $front->setRouter(new Custom_Controller_Router_Cli());
    $front->setResponse(new Zend_Controller_Response_Cli());
    $front->throwExceptions(true);
    $front->addModuleDirectory(dirname(__FILE__) . '/application/modules');
    $front->dispatch();
}

Custom_Controller_Router_Cliはこんな感じ。

<?php
require_once 'Zend/Controller/Router/Interface.php';
require_once 'Zend/Controller/Router/Abstract.php';

class Custom_Controller_Router_Cli extends Zend_Controller_Router_Abstract implements Zend_Controller_Router_Interface
{
    public function assemble($userParams, $name = null, $reset = false, $encode = true) {}
    public function route(Zend_Controller_Request_Abstract $dispatcher) {}
}

基本的には以上で実行できるが

■アクセスコントロールの設定

アクセスコントロールを行っている場合は上述のコードよりも先にアクセスできるようにしなければならない。以下は一例。

$sesion = new Zend_Session_Namespace('global');
$sesion->userLevel = 'admin';
$acl = new Zend_Acl();
$acl->addRole(new Zend_Acl_Role('guest'));
$acl->addRole(new Zend_Acl_Role('admin'), 'guest');
$acl->add(new Zend_Acl_Resource('guestPage'));
$acl->add(new Zend_Acl_Resource('adminPage'));
$acl->allow('guest');
$acl->allow('admin');
$acl->deny('guest', 'adminPage');
$acl->allow('admin', 'adminPage');
Zend_Registry::set('acl', $acl);

基本的には一般ユーザが閲覧(実行)できる場所に、このファイルを配置するのは良くない。

2010年2月14日

PHPの定数とOS

カテゴリー: PHP — admin @ 10:45 PM

■OS

OS名

echo PHP_OS;

■path

パスを区切る文字

echo PATH_SEPARATOR;// linux => ';', win => ':'

■directory

ディレクトリを区切る文字

echo DIRECTORY_SEPARATOR;// linux => '/', win => '\'

2010年2月10日

linuxで同時に開けるソケット数を確認する

カテゴリー: Linux, PHP — admin @ 12:37 AM

以下のコマンドで確認する。

/sbin/sysctl -a|grep "somax"

PHPでは以下の定数で定義される。

SOMAXCONN

2010年1月29日

mb_ereg系関数が使えない

カテゴリー: Linux, PHP — admin @ 1:46 AM

EC-CUBEが使えなかったりする。

yum install php-mbstring

コンパイルは面倒だからyumする。

2010年1月20日

Cookieを使って別サイトの閲覧履歴を取る

カテゴリー: PHP, ウェブサイト制作 — admin @ 1:42 AM

自社サイトを訪れたユーザが他サイトAを訪れたか調べたい。他サイトAに対してビーコンを貼れることを条件に、これが可能となる。

■他サイト側(http://sample.jp/index.html)

imgタグでビーコンを貼り付けてあげれば良い。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>ドキュメント</title>
</head>
<body>
<p><img src="http://sample.org/spacer.php" width="1" height="1" /></p>
</body>
</html>

■自社(サイト)ドメイン側実装

他サイトに貼り付けたビーコンを準備してあげる。

ビーコン用のイメージ(http://sample.org/spacer.php)

クッキーをセットしたいのでphpで書く。

<?php
header('Content-Type: image/gif');
setcookie('sample', 'see');
print(file_get_contents('spacer.gif'));

検証ページ(http://sample.org/index.php)

このページを訪問したユーザが、他サイトAを訪問したか調べられる。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>検証ページ</title>
</head>
<body>
<?php
if($_COOKIE['sample'] === 'see'){
    print('<p>you have already seen http://sample.jp</p>');
}
else{
    print('<p>Nice to meet you!</p>');
}
?>
</body>
</html>

基本的にはユーザの行動収集はこの原理で行う。iframeとJavaScriptを使用することで、さらに多くの情報を取得することができる。

2010年1月13日

Yahooひらがな変換API

カテゴリー: PHP — admin @ 12:05 AM

ドキュメントの文字コードはutf-8である。

<?php
$str = urlencode('庭には二羽鶏がいる。');
$url = "http://jlp.yahooapis.jp/FuriganaService/V1/furigana?appid=<apikey>&sentence={$str}";
$xml = new SimpleXmlElement($url, null, true);
var_dump($xml);
/*
object(SimpleXMLElement)#1 (1) {
  ["Result"]=>
  object(SimpleXMLElement)#2 (1) {
    ["WordList"]=>
    object(SimpleXMLElement)#3 (1) {
      ["Word"]=>
      array(8) {
        [0]=>
        object(SimpleXMLElement)#4 (3) {
          ["Surface"]=>
          string(3) "庭"
          ["Furigana"]=>
          string(6) "にわ"
          ["Roman"]=>
          string(4) "niwa"
        }
        [1]=>
        object(SimpleXMLElement)#5 (3) {
          ["Surface"]=>
          string(3) "に"
          ["Furigana"]=>
          string(3) "に"
          ["Roman"]=>
          string(2) "ni"
        }
        [2]=>
        object(SimpleXMLElement)#6 (3) {
          ["Surface"]=>
          string(3) "は"
          ["Furigana"]=>
          string(3) "は"
          ["Roman"]=>
          string(2) "ha"
        }
        [3]=>
        object(SimpleXMLElement)#7 (3) {
          ["Surface"]=>
          string(6) "二羽"
          ["Furigana"]=>
          string(6) "にわ"
          ["Roman"]=>
          string(4) "niwa"
        }
        [4]=>
        object(SimpleXMLElement)#8 (3) {
          ["Surface"]=>
          string(3) "鶏"
          ["Furigana"]=>
          string(12) "にわとり"
          ["Roman"]=>
          string(8) "niwatori"
        }
        [5]=>
        object(SimpleXMLElement)#9 (3) {
          ["Surface"]=>
          string(3) "が"
          ["Furigana"]=>
          string(3) "が"
          ["Roman"]=>
          string(2) "ga"
        }
        [6]=>
        object(SimpleXMLElement)#10 (3) {
          ["Surface"]=>
          string(6) "いる"
          ["Furigana"]=>
          string(6) "いる"
          ["Roman"]=>
          string(3) "iru"
        }
        [7]=>
        object(SimpleXMLElement)#11 (1) {
          ["Surface"]=>
          string(3) "。"
        }
      }
    }
  }
}
*/
foreach($xml->Result->WordList->Word as $word){
    print($word->Furigana);
}
//にわにはにわにわとりがいる

文字コードがshift-jisの場合は以下のようになる。

$str = urlencode(mb_convert_encoding('庭には二羽鶏がいる。', 'utf-8', 'sjis'));
$url = "http://jlp.yahooapis.jp/FuriganaService/V1/furigana?appid=<apikey>&sentence={$str}";
$xml = new SimpleXmlElement($url, null, true);
foreach($xml->Result->WordList->Word as $word){
    print($word->Furigana);
}

API

2010年1月12日

ZendFrameworkビュースクリプトでのbodyタグ

カテゴリー: CSS, PHP, ZendFramework, ブラウザ — admin @ 2:19 AM

以下のように記述するとcssで装飾しやすい気がする。

■コントローラ

public function init(){
    $this->_view->module     = $this->_getParam('module');
    $this->_view->controller = $this->_getParam('controller');
    $this->_view->action     = $this->_getParam('action');
}

■ビュー

<body class="<?php print($this->controller); ?>" id="<?php print($this->controller); ?>_<?php print($this->action); ?>">

ちなみに以下のようになっている。

print($this->module);//モジュール名
print($this->controller);//コントローラ名
print($this->action);//アクション名

出力例

<body class="category" id="category_register">

参考

以下の例の場合を考えてみる。

<body class="<?php print($this->module); ?> <?php print($this->controller); ?> <?php print($this->action); ?>">
出力例
<body class="category" id="category_register">

一見素晴らしいが、IEが以下のセレクタに対応していないため使用できない。

body.admin.category.register {
	background-color: red;
}
body.register {
	background-color: blue;
}

上述のように記述するとIE6のみbodyの背景色がblueになるはずだ。

2010年1月10日

Zend_Exceptionのメソッド

カテゴリー: ZendFramework — admin @ 3:48 AM

以下の通り。

array(10) {
  [0] => &object(ReflectionMethod)#54 (2) {
    ["name"] => string(7) "__clone"
    ["class"] => string(9) "Exception"
  }
  [1] => &object(ReflectionMethod)#55 (2) {
    ["name"] => string(11) "__construct"
    ["class"] => string(9) "Exception"
  }
  [2] => &object(ReflectionMethod)#56 (2) {
    ["name"] => string(10) "getMessage"
    ["class"] => string(9) "Exception"
  }
  [3] => &object(ReflectionMethod)#57 (2) {
    ["name"] => string(7) "getCode"
    ["class"] => string(9) "Exception"
  }
  [4] => &object(ReflectionMethod)#58 (2) {
    ["name"] => string(7) "getFile"
    ["class"] => string(9) "Exception"
  }
  [5] => &object(ReflectionMethod)#59 (2) {
    ["name"] => string(7) "getLine"
    ["class"] => string(9) "Exception"
  }
  [6] => &object(ReflectionMethod)#60 (2) {
    ["name"] => string(8) "getTrace"
    ["class"] => string(9) "Exception"
  }
  [7] => &object(ReflectionMethod)#61 (2) {
    ["name"] => string(11) "getPrevious"
    ["class"] => string(9) "Exception"
  }
  [8] => &object(ReflectionMethod)#62 (2) {
    ["name"] => string(16) "getTraceAsString"
    ["class"] => string(9) "Exception"
  }
  [9] => &object(ReflectionMethod)#63 (2) {
    ["name"] => string(10) "__toString"
    ["class"] => string(9) "Exception"
  }
}
次ページへ »