Posts tagged PHP
CakePHP コントローラのメソッドをURLから実行させない
0コントローラにアクション以外のメソッドを書かないのが一番いいのかもしれません。
ただ、どうしても書きたいという場合にはメソッド名にアンダーバー “_” を付けるとURLからアクセスできなくなります。
試しに posts_controller.php に _foo というメソッド名を作り /posts/_foo/ にアクセスしてみると
Private Method in PostsController
You are seeing this error because the private class method _foo should not be accessed directly.
とプライベートメソッドなのでアクセスできませんよというエラーメッセージが出力されました。
しかしこのメッセージってあまりよくないのではと思い、試しに DEBUG=0 とデバッグモードを本番環境用にしたところ、
Not found
The requested address posts/_foo/ was not found on this server.
となりました。やはり考えてますよねそれくらい。
ちなみにエラーメッセージは
/cake/libs/view/templates/errors/
にエラーの種類によって15のテンプレートが用意されています。
自分で Not found などのエラーを修正したい場合は
/cake/libs/view/templates/errors/error404.thtml
を
/app/views/errors/error404.thtml
にコピーして修正すればそちらのテンプレートが使用されます。
CakePHP の日本語マニュアルに書かれている
メンバ関数を protected にして見えるようにするには、コントローラアクション名を ‘-’ ではじめてください。(訳注:将来の仕様???)
メンバ関数を private にするためには、コントローラアクション名を ‘–’ ではじめてください。(訳注:将来の仕様???)
というのはこれのことなのかな?
ただ、”_” ではなく “-” になっている。(英語のマニュアルも同様に “-” でした。)
CakePHP 日本語マニュアル
C.4. コントローラ(Controllers)
CakePHP マニュアル(英語)
CakePHP Manual
CakePHP htmlヘルパーでラジオボタンを離れた場所に分けて書く方法
1html ヘルパーでラジオボタンを書く場合
<?php echo $html->radio('Model/field', array('1'=>'option1','2'=>'option2', '3'=>'option3')); ?>
のように書くと、ラジオボタンを横に並べて表示させることができます。
ただ、デザインによってはテーブルなどを使用していたり縦に並べたりして、ひとつづつ表示させたいときもあると思います。
その場合は
<?php echo $html->radio('Model/field', array('1'=>'option1')); ?> <?php echo $html->radio('Model/field', array('2'=>'option2')); ?> <?php echo $html->radio('Model/field', array('3'=>'option3')); ?>
とすれば、それぞれのボタンを希望の位置に表示させることができます。
CakePHP html ヘルパーでラジオボタンの選択状態 (checked) を指定する方法
1html ヘルパーを使用してラジオボタンの選択状態 (checked) を指定する方法です。
下記のようにすると option2 にチェックがつきます。
<?php echo $html->radio('Model/field', array('1'=>'option1','2'=>'option2', '3'=>'option3'), null, array('value'=>'2'), false); ?>
第4パラメータの array(‘value’=>’2′) でチェックするボタンを指定しています。
キーの ‘value’ は固定で、値の’2′ の方をチェックしたいラジオボタンの value 属性の値と同じものを指定すれば、そのボタンがチェックされます。
デフォルトや以前入力された状態を表示するために使用できそうです。
CakePHP html ヘルパーでラジオボタンを表示する
0htmlヘルパーで radio ボタンを表示させるには下記のようにします。
下記の例では3つのラジオボタンを表示しています。
<?php echo $html->radio('Model/field', array('1'=>'option1','2'=>'option2', '3'=>'option3'), ' | ', array('onchange'=>'alert(this.value)'), false); ?>
表示される HTML は下記のようになります。
(実際には1行で出力されますが改行を入れています)
<input type="radio" name="data[Model][field]" id="field_1" onchange="alert(this.value)" value="1" />option1 | <input type="radio" name="data[Model][field]" id="field_2" onchange="alert(this.value)" value="2" />option2 | <input type="radio" name="data[Model][field]" id="field_3" onchange="alert(this.value)" value="3" />option3 |
radio メソッド
string radio(string $fieldName, arrray $options [,string $inbetween=null [,array $htmlAttributes=array() [,bool $return=false ]]])
- $fieldName
- name属性の値
- $option
- array(‘value’=>’表示名’);
value は value=”value” になり、表示名はラジオボタンの後ろに表示される文字名 - $inbetween
- ラジオボタンの間に表示される文字列
- $htmlAttributes
- html の属性 array(‘属性名’=>’値’)で指定する
- $return
- ヘルパーの自動出力を抑止する(参考:ヘルパーの出力を echo を使わずに出力する方法)
CakePHP ヘルパーの出力を echo を使わずに出力する方法
2※この投稿の方法はバージョン1.1 までしか使用できないようです。1.2 のソースを確認したところ、$html->input の$return パラメータはなくなっていました。/app/config/core.php に AUTO_OUTPUT という定数もなくなっていました。ご注意ください。
Cakephp のヘルパーを使用していて
<?php echo $html->input('Model/filed', array()); ?>
と書くところを
<?php $html->input('Model/field', array()); ?>
と echo を使用せずに出力するには
/app/config/core.php
AUTO_OUTPUT = true;
にすれば、自動的に出力するようになります。
私はつい echo を書き忘れてしまうので助かります。
ヘルパーのメソッドの $return パラメータを true にするとこの AUTO_OUTPUT を無効にすることもできます。
ただ、各メソッドによって、$return パラメータの位置がバラバラなので、書くときにはヘルパーのソースを確認する必要があるかと思います。
ちなにみに input の場合は
<?php $html->input('Model/field', array(), true); ?>
とすると自動出力を抑止できますので、上記は何も表示されなくなります。
CakePHP 日本語マニュアル
10章 ヘルパー
CakePHP アソシエーションのまとめ(4)
0まとめ(1) では1対1のアソシエーション hasOne でしたが、
今回は1対多のアソシエーション hasMany です。
例えば、一人のユーザに複数のコメント投稿があるような場合です。
データベースは
CREATE TABLE users( id int unsigned auto_increment primary key, nickname varchar(30) NOT NULL, created datetime default NULL, modified datetime default NULL ); CREATE TABLE posts( id int unsigned auto_increment primary key, user_id int unsigned unique, comment text, created datetime default NULL, modified datetime default NULL );
のような場合、アソシエーションの定義は下記のようになります。
< ?php class User extends AppModel { var $name = 'User'; var $hasMany = array('Post' => array('className' => 'Post', 'conditions' => '', 'order' => '', 'foreignKey' => 'user_id', 'dependent' => true, 'exclusive' => false, 'finderQuery' => '' ) ); } ?>
これで、
$this->User->findById($id);
とすると下記のようにデータを取得できます。
Array ( [User] => Array ( [id] => 1 [nickname] => boze ) [Post] => Array ( [0] => Array ( [id] => 1 [user_id] => 1 [comment] => コメント1です ) [1] => Array ( [id] => 1 [user_id] => 1 [comment] => コメント2です ) .... ) );
また、hasOne などと同様に CakePHP の命名規約に従っていれば、foreignKey は指定しなくても大丈夫ですので、最低限
var $hasMany = array('Post');
でもアソシエーションを定義できます。
また、hasMany で指定する配列の意味は下記の通りです。
className
関連付けたいモデルのクラス名
conditions
hasMany で取得したいデータの条件を指定する。 SQL の条件文。
order
関連するモデルのデータの並び順。SQL の ORDER 句の指定方法。
Post.created DESC
テーブル名をカラム名の前に付けないと、User.created と区別できません。
limit
Cake が取り出す関連モデルのデータの最大数。
‘limit’ => 5 のように数字で指定。
foreignKey
関連しているモデルを指している外部キーの名前。
Cake の命名規約に従っている場合は省略可能。従っていない場合はここで指定する。
dependent
true に設定すると、モデルのデータの削除時に関連しているモデル側のデータも削除される。
exclusive
true に設定すると、関連しているすべてのオブジェクトが一つの SQL ステートメントで削除される。
finderQuery
アソシエーションを取り出すために、完全な SQL ステートメントを指定する。
CakePHP 日本語マニュアル
6.4. アソシエーション
PHP の便利な関数 output_add_rewrite_var
1PHP から出力する HTML に最終的に a タグや form タグを見つけ出し、自動で指定した変数をクエリストリングや hidden 属性で挿入してくれる関数です。
PHP4.3 から追加されたようなのですが知らなかったです。
昔から、session.use_trans_sid というセションID を a タグや form タグの hidden 属性に追加してくれるのはありましたが、それをセションID 以外にも使用できるように関数化したもののようです。
URL リライト機構に新しい名前/値の組を追加します。 名前および値は、URL (GET パラメータとして) およびフォーム (hidden フィールドとして) で追加されます。これは、session.use_trans_sid で透過的 URL リライティングが有効になっている場合に セッション ID が渡される方法と同じです。 絶対 URL (http://example.com/..) はリライトされないことに注意しましょう。
- PHP マニュアルより
userid の値 $userid を全てのリンクに付与したい場合は、
output_add_rewite_var('userid', $userid);
と書くことにより
<a href="index.php">TOP</a>
が
<a href="index.php?userid=1">TOP</a>
と出力されます。
form タグも
<form action="index.php" method="post">
が
<input type="hidden" name="userid" value="1">
となります。
注意点としては絶対URLはりライトされないことです。
これがないと他サイトにまで、セションID などを渡してしまいますからね。
PHP マニュアル
output_add_rewrite_var
CakePHP アソシエーションのまとめ(3)
1今回は belongsTo です。
CakePHP アソシエーションのまとめ(1) で hasOne をやりましたが、belongsTo はその逆です。
まとめ(1) で使用したテーブルで説明すると、Profile モデルにUser モデルを関連付けるのが belongsTo になります。
profile.php
<?php class Profile extends AppModel { var $name = 'Profile'; var $belongsTo = array('User' => array('className' => 'User', 'conditions' => '', 'order' => '', 'foreignKey' => 'user_id' ) ); } ?>
配列のそれぞれの意味は CakePHP アソシエーションのまとめ(2) に説明があります。
これで、
$this->profile->findById($id);
とかすると、Profile モデルの該当するID のデータ内容とそのProfile モデルの元の User モデルのデータが取得できます。
もちろん、CakePHP の命名規則に従っていれば、
profile.php
<?php class Profile extends AppModel { var $name = 'Profile'; var $belongsTo = array('User'); } ?>
でもいけます。
WordPress でタグを使えるようにしてみた
2使用したプラグインは Simple Tagging です。
WordPress用、タグ付けプラグイン:Simple Tagging | 創造マラソン
こちらのサイトでかなり詳しく解説されています。
Single.php のエントリー本文の後に
<?php STP_PostTags(); ?>
を入れて、タグを表示させ、さらに
< ?php STP_RelatedPosts(); ?>
でタグにより、関連するエントリーを表示させるようにしました。
また、サイドバーに
< ?php STP_Tagcloud(); ?>
を入れてタグクラウドを表示させました。
ただ、このままではリスト構造で縦に並んでしまうので、
Tag Cloud – Simple Tagging for WordPress – Trac
こちらを参考に下記を追加しました。
style.css
ul#tagcloud { padding:0; margin:0; text-align:center; list-style:none; } ul#tagcloud li { display:inline; font-size:70%; color:#ccc; background: none; padding: 0;} ul#tagcloud li a, ul#tagcloud li a:link { text-decoration:none; } ul#tagcloud li a:hover { text-decoration:underline; } ul#tagcloud li.t1 a { color:#797979; font-size: 120%; } ul#tagcloud li.t2 a { color:#6d6d6d; font-size: 160%; } ul#tagcloud li.t3 a { color:#616161; font-size: 190%; } ul#tagcloud li.t4 a { color:#555555; font-size: 210%; } ul#tagcloud li.t5 a { color:#484848; font-size: 230%; } ul#tagcloud li.t6 a { color:#3c3c3c; font-size: 250%; } ul#tagcloud li.t7 a { color:#303030; font-size: 270%; } ul#tagcloud li.t8 a { color:#242424; font-size: 290%; } ul#tagcloud li.t9 a { color:#181818; font-size: 310%; } ul#tagcloud li.t10 a { color:#0c0c0c; font-size: 330%; }
いよいよ PHP5 への移行が進むか
0ついに来ましたか。。。2007/12/31いっぱいはサポートを続け、2008/08/08までは致命的なセキュリティFIXのみ行うようです。
最近の開発では PHP5 が増えてきましたし、いよいよPHP5 への移行が加速しそうですね。
個人的にはPHP5 は大歓迎です。