ボタンジェネレーター  ジフローダージェネレーター  リントチェッカー  ベーシック認証作成  いけてるサイト
参考サイトリンク集  ビジネス文例集  ブラウザ検証  flaデーター(Movies→Games→Full_Game_Source)
CakePHP規約ワードメーカー

■MySQLを外部から接続したい
インスタンスを複数立ててMySQLは他のサーバーから接続したい。
結構ハマったこと→セキュリティーグループにMySQLを追加。

■さしあたって使うものの概要
S3 : ファイル置場、ローカルからファイルの上げ下げを行う。S3←→EC2とかのやりとりも。
EC2
├Instances : サーバー本体。
├Volumes : 外付けディスク。EC2からしか見えない。マウントして使う。よくEBSと呼ばれる。
└Snapshots : バックアップイメージ。ここからVolumesを復活できる。

■Instances
インスタンスはリブート、ストップ、スタートがブラウザから出来ます。
ターミネイトは完全削除です。全部消えるので注意。
ec2-xx-xx-xx-xx.compute-1.amazonaws.com
xx-xx-xx-xxなのが外向きのIPです。リブートしたら変わります。
固定にしたいときにはそういう契約が追加であります。
しないときはあげっぱなしで良いのではないでしょうか。

■Volumes
インスタンスはAMIというイメージでバックアップが取れますが、/dev/sda1の10GB部分だけなので、大量のファイルはVolumesをくっつけて置きます。
ここに置いたものはSnapshotsで簡単にバックアップが取れるし復活できるので便利です。

■S3
ファイルのアップロードはEC2に直接WinSCPからでも出来ますが激重なので、いったんS3にあげてからEC2にコピーします。
S3にはブラウザのメニューからもアップできますが1ファイル辺り最大300MBまでです。
大きなファイルはFireFoxのアドオン「S3 Firefox Organizer」を使うと良いです。

■ツール
ローカルパソコンからEC2に命令できます。
最初に構築したり運用したりするときには、Linuxの中に入っていつものように作業することの他に、ローカルパソコンからEC2専用のコマンドをたたいて作業することになります。(ブラウザから出来ることが増えたので減りはしてます)
手前のLinuxにツールを入れた例。
jre-6u23-linux-i586-rpm.bin
をダウンロードしてWinSCPで手元のLinuxサーバーに置き実行権限を与える。
chmod a+x jre-6u23-linux-i586-rpm.bin
実行
./jre-6u23-linux-i586-rpm.bin
環境変数設定(ターミナル閉じるまで有効)
/home/admin/ec2/に解凍した場合
export JAVA_HOME=/usr
export EC2_HOME=/home/admin/ec2/ec2-api-tools
export PATH=$PATH:$JAVA_HOME/bin:$EC2_HOME/bin
export EC2_PRIVATE_KEY=/home/admin/ec2/pk-xxxxxx.pem
export EC2_CERT=/home/admin/ec2/cert-xxxxxx.pem
ec2ver
でバージョンがでたらOK

キーファイルはブラウザの管理画面から Account → Security Credentials → X.509証明書でダウンロードして置いてください。

■EBSのマウント
ブラウザからVolumesを作ります。
このときくっつけたいインスタンスと同じゾーン(us-east-1cみたいなの)にしないといけません。
容量は任意で。
できたらツールで以下のコマンド。
ec2-attach-volume -d /dev/sde -i i-xxxxxxxx vol-xxxxxxxx
 i-xxxxxxxx : インスタンスのID(EC2 Instance)
 vol-xxxxxxxx : EBSのVolumeID
 ↑ブラウザの管理画面で見れます。
 /dev/sde は sdc,sdd,...... などと試して空いているところを探してください。
yes | mkfs -t ext3 /dev/sde
mkdir /data
mount /dev/sdf /data
 /dataというディレクトリを作ってマウントした場合。

■EBSのバックアップ
ブラウザから EC2→Volumes Create Snapshot をしておきます。

■EBSから復旧
ブラウザから EC2→Snapshots Create Volume で新しいディスクを作ります。
できたら上と同じように以下コマンドを実行します。
ec2-attach-volume -d /dev/sdg -i i-xxxxxxxx vol-xxxxxxxx
mount /dev/sdf /data
 mkfsはいりません。

■S3→EC2
rubyでできたツールなので、まずrubyをインストールします。
yum install ruby
s3sync.tar.gz をダウンロードしてきてサーバー(インスタンス)に置きます。
以下/root/の下に置いた例。
cd /root
tar xvfz /some/where/s3sync.tar.gz
mkdir .s3conf
chmod 700 .s3conf

cat > ~/.s3conf/s3config.yml << E-O-F
aws_access_key_id: xxxxxxxxxxxxx
aws_secret_access_key: xxxxxxxxxxxxxxxxxxxxx
E-O-F

xxxxxxxxxxxxはブラウザの管理画面から Account → Security Credentials あたりにあります。
いちいちログインしなおさないといけなくて不便。

ディレクトリ構成はこう。
/root/.s3conf
/root/s3sync

◆バケット一覧表示
/root/s3sync/s3cmd.rb listbuckets
 hoge1
 hoge2

◆バケット内リスト
/root/s3sync/s3cmd.rb list hoge1

◆ファイル取得
/root/s3sync/s3cmd.rb get hoge1:hage1.tgz hage1.tgz

 一度使えなくなって、インスタンスを再起動したら直ったことが有ります。勘違いかもだけど。

■インスタンスを作るときの注意
なにとなくクイックスタートから選んでいたら、高機能高額のものになていました。
Community AMIs タブで 32-bit centos とかで検索したら安いのを選べます。
Account → Security Credentials → アカウントアクティビティ でときどき料金の確認をしよう。

■セッションに検索条件を保存
$this->Session->write('searchItems', $searchItems);

■セッションに保存された検索条件を読込
$searchItems = $this->Session->read('searchItems');

■セッションを破棄
$this->Session->delete('searchItems');

■店舗にぶら下がっているユーザーにぶら下がっているレコードとか
App::import('Model', 'User');
$User = new User();
$sql = "SELECT id FROM users WHERE shop_id = 104";
$userData = $User->query($sql);
$user_ids=array();
foreach ($userData as $user_id) {
array_push($user_ids,$user_id['users']['id']);
}
$searchItems['conditions'] = array($this->uses[0].'.user_id' => $user_ids);

■その他 form.php の初期設定
セレクトボックスのセパレーターをスペースにして、月名を数字に
/app/views/helpers/form.php L1700付近
$elements = array('Day','Month','Year','Hour','Minute','Meridian');
// $defaults = array(
// 'minYear' => null, 'maxYear' => null, 'separator' => '-',
// 'interval' => 1, 'monthNames' => true
// );
$defaults = array(
'minYear' => null, 'maxYear' => null, 'separator' => ' ',
'interval' => 1, 'monthNames' => false
);

■年月日
もう日本の場合以下で良いと思う。いちいちオプション書くの手間だし。
/app/views/helpers/form.php L764
//  $dateFormat = 'MDY';
  $dateFormat = 'YMD';

■ラジオボタンの初期値
e($form->radio('status',array('0'=>'使用可','1'=>'使用不可'),array('default' => 1)));
又は
e($form->input('status',array('type' => 'radio', 'options' => array('0'=>'使用可','1'=>'使用不可'), 'default' => 1)));
上記の場合、
DBから取り寄せたデーターが0のとき、default値へ強制的に1が代入されてしまう。
これはcakeのバグ(emptyで判定しているので値が0の時におかしくなる)なので、以下を修正。
appの下にコピーして使うかどうかは任意。
/cake/libs/view/helper.php L598
if (is_array($options)) {
//  if (empty($result) && isset($options['default'])) {
  if (is_null($result) && isset($options['default'])) {
    $result = $options['default'];
  }
  unset($options['default']);
}

■文字化け
CakePHPだけの問題ならこれ。
/app/config/database.php
var $default = array( とかに以下の1行を追加。(例はUTF8の場合)
'encoding' => 'utf8',

■携帯サイトで、ログインできない
正確には、ログインできたかのように見えて、他のページに遷移したらログインページに戻される、という感じです。
結論から言うと core.php の Session.checkAgent を false にすると良いです。
◆調べ方
app以下で解決しなかった場合、セッション関係なら以下の場所を調べます。
なにかしら推測できることがあれば怪しい場所を重点的に調べますが、皆目検討が付かないときは、もう片っ端から error_log を挟んでしらみつぶしに調べます。
/cake/libs/session.php
/cake/libs/controller/components/auth.php
/cake/libs/controller/components/session.php
◆今回の原因
Session.checkAgent を true にしていると、ユーザーエージェント情報が途中で変わったらセッションを切ります。
ユーザーエージェントが途中で変わるなんてことが普通に有り得るの?
と思いますが、何故かありました。犯人は以下。なぜかこいつが割り込んできます。

Nokia6820/2.0 (4.83) Profile/MIDP-1.0 Configuration/CLDC-1.0 (compatible; Mediapartners-Google/2.1; +http://www.google.com/bot.html)

エラーになるパターンには Google AdSense を貼り付けているページがあったらしいので、何かしら影響を及ぼしているのだと思う。設置した人が何をしたのか、Googleの仕様がどうなのか、を調べ上げるより core.php の設定を変えるほうが手っ取り早いのでそうしようそうしよう。
変なサイトへのリンクが設置されていなければ大丈夫だろう。
セッションジャックが怖ければこのへんに任意のカスタマイズをすれば良いです。

■$this->redirect ちゃんとリダイレクトしない
携帯で他サイトにあるリンクから戻ってきたときに、しばらくの間はセッションを維持しようと思い、$this->MOBILE_DATA['uid']を利用して実現しようと思ったら、どうもリダイレクトのところで上手くいかない。
URLを直接入力したらOKだったのだけど。
調べて見たら、/cake/libs/session.php L433 で、セキュリティーレベル medium 以上だと外からのリファラは強制的にセッションを切られていました。
switch ($this->security) {
 case 'high':
  $this->cookieLifeTime = 0;
  if ($iniSet) {
   ini_set('session.referer_check', $this->host);
  }
 break;
 case 'medium':
  $this->cookieLifeTime = 7 * 86400;
  if ($iniSet) {
   ini_set('session.referer_check', $this->host);
  }
 break;
 case 'low':
 default:
  $this->cookieLifeTime = 788940000;
 break;
}
ここらへんをコメントで止めるか、low にします。
或いは任意のカスタマイズを行います。
/cake/以下に手を加えるのは好ましくないのですが、どうしても触らないといけない時もありますので、バカの一つ覚えにならないように。
もしバージョンアップがあればチェックし直すのは言うまでもありません。

■正規表現
右辺だけで「AとBいずれにもマッチしない」みたいなもの。
テキストエリアのバリデーションの例。
var $validate = array(
  'title' => array(
    'rule' => 'notEmpty',
    'message' => 'タイトルを入力して下さい',
  ),
  'content' => array(
    array(
      'rule' => 'notEmpty',
      'message' => '内容を入力して下さい',
    ),
    "custom" =>
      array("rule" => array("custom", '/(?=^(?:(?!submit).)*$)(?=^(?:(?!javascript).)*$)/si'),"message" => "不正なコードが含まれています。(submit,javascript等)", "allowEmpty" => true),
  ),
);

■画面がまっしろ
Fatal error: Call to undefined function
データーベースの接続がおかしいなら以下を疑う。
・MySQLが起動しているか。
・/app_gal/config/database.php が間違ってないか。
・MySQLにgrant でユーザー・パスワード等を設定しているか。
 (例、GRANT SELECT , INSERT , UPDATE , DELETE ON *.* TO username@"%" IDENTIFIED BY 'passwd' WITH GRANT OPTION;)
・yum install php-mysql したか。
・Apache、MySQL 再起動。

■conditions で同じカラムをANDで繋ぐ
スペースを入れます。
$shop_id_array=(1,2,3,4,5);
$shop_id_array2=(2,4,6);
$ShopObj = ClassRegistry::init("Shop");
$shop_data = $ShopObj->find("all", array(
  "fields" => array('id','name','domain'), // 後ろのidの前にスペース
  "conditions" => array('id' => $shop_id_array2, ' id' => $shop_id_array),
  "order" => array('name'),
  )
);

■belongToとかをコントローラーで使う直前に宣言する。
function anotherAction() {
 // leader.php モデルファイル内には
 // Leader hasMany Principle がないのでここでは
 // Leader のみ取得します。
 $this->Leader->findAll();
 // bindModel() を使用して Leader モデルに新しい関連を
 // 追加しましょう:
 $this->Leader->bindModel(
  array('hasMany' => array(
   'Principle' => array(
    'className' => 'Principle'
   )
  )
  )
 );
 // 正しく関連付けされたので
 // 1回の find 関数で Leader を取得すると
 // 関連する Principle も取得されます:
 $this->Leader->findAll();
}

■belongToとかをコントローラーで使う直前に宣言する。(ページネイト)
$this->Model->unbindModel(array('hasOne'=>array('Model_2')),false);
$this->Model->bindModel(array('hasOne'=>array('Model_3')),false);
$result = $this->paginate('Model');

■CSSの変更
/app/webroot/css/cake.generic.css

■DBからにランダム表示(3件)する
$home_theme = $this->Theme->find('all', array(
'limit'=>3,
'order'=>'rand()',
));
'order'=>'rand()'はCakePHPではなくMySQLの実装("order by rand()")です。

■find('all')とpaginate()の違い
find('all)の引数はハッシュ、paginate()の引数は配列みたいな。
例)
$conditions = array("Entry.contents LIKE" => "%".$contents."%");
$this->paginate($conditions);//1つめの引数が条件文というルール。
if($conditions){$where['conditions']=$conditions;}
$list = $this->Entry->find('all',$where);//'conditions'という文字列で条件文とする。

■URLとプログラム
ドメイン/コントローラー名/アクション名/
例えば
http://hoge.net/hoge/index/だと
/controller/hoge_controller.php内のindex()が処理をします。ビューは/views/hoge/index.ctpになります。

■既存のデーターで認証ができない
CakePHPのAuthコンポーネントはパスワードを自動的に暗号化してしまうので、既存のパスワードはそのまま使えません。解決方法は以下の2点。
・パスワード暗号化を無効化する。
・既存のパスワードを暗号化する。

■コンディションズ
$conditions=array();
$conditions=array("EditorBlogComment.editor_blog_id in (select id from editor_blogs where editor_blog_category_id =$kind and del_flg='0')","del_flg"=>0);
$comments = $this->EditorBlogComment->find('all',array('conditions'=>$conditions,'limit' => 10, 'order' => array('EditorBlogComment.id' => 'desc')));
--------------------
$this->paginate = array('order' => array('Hoge.ranking_pv_pc' => 'desc')); 
--------------------
$conditions = array("Entry.editor_blog_category_id" => 1,"Entry.del_flg" => 0);
$orders = array("Entry.id DESC");
$e_blog = $this->Entry->find('all',array('conditions'=>$conditions,'order' => $orders,'limit' =>3));
--------------------
$conditions = array("or" => array (
 "name LIKE" => "%".$keyword."%",
 "telephone LIKE " => "%".$keyword."%",
 "post_address LIKE " => "%".$keyword."%"
), "id" => $form_shops);
$this->set('shoplists', $this->paginate($conditions));
--------------------
$conditions = array("hoge_id" => $hoges, "Fuga.order_no" => 1, "Fuga.del_flg" => 0);
$proshots = $this->Fuga->find('all',array('conditions'=>$conditions));
--------------------
$orderby = 'Hoge.'.$this->params['form']['orderby'];
$this->paginate = array( 'limit' => 18, 'order' => array($orderby => 'desc')); 
$res = $this->Hoge->find('all',array('conditions'=>$conditions));
--------------------
unset($conditions['personality'][$key]);

■コントローラーからビューに変数を渡す
コントローラー側
$this->set('hoge', $hoge);
ビュー側
echo $hoge;
連想配列とかも可です。

■コントローラーが無いとき
  //既に作成済みのコントローラーを配列に納めとく。
  $reservednames=array('members', 'posts', 'entries', 'tags'); 

  //リクエストされたコントローラ名を取得
  if(! empty($fromUrl)) list($request_controller) = explode("/", $fromUrl); 

 if(! empty($request_controller)){
  //リクエストされたコントローラ名がサイトで使用されてなければ、、、
  if(array_search($request_controller, $reservednames) ===false){
   //リクエストされたコントローラ名をユーザ名として、
   //マイページ用のコントローラとアクションにアクセスする
   Router::connect('/*', array('controller' => 'users', 'action' => 'index'));
  }
 }

■コントローラーの最初で宣言するもの
class HogessController extends AppController {
var $name = 'Hogees'; //自分の名前
var $uses = array('Hoge', 'User'); //使用するテーブル名(頭大文字の単数形)複数選択可
var $helpers = array('Html', 'Form'); //使用するヘルパー名
var $components = array('Confirm'); //使用するコンポーネント名
$users, $helpers, $commponents はいらないなら無くても可。
テーブル名に添った形のコントローラーでテーブルを読まないときは以下。
public $uses = null;

■コントローラー名以外のビューとかレイアウトとか
public $layout = 'custom'; // コントローラー全体
function index() {
 $this->layout = 'custom'; // レイアウト変更
 $this->render('index2'); // ビュー変更
 $this->render('index', 'custom'); // ビューまで変えるとき。
}

■コンポーネント
コントローラーの部品は以下に置きます。
/app/controllers/components/
ビューの部品
/app/views/helpers/

■チェックボックスの作り方
echo $form->input('exclusion_shop', array('options' => $shoplists, 'type' => 'select', 'multiple' => 'checkbox', 'selected' => $selectedshops, 'label' => '対象外の個店'));
selectedをlabelの後ろに書いてたらエラーになっていて悩んだ。

■ディレクトリ構造
/app/以下の部分だけ触ります。
/cake/lib/以下に各機能の基ネタがありますので、同じ位置関係にあるファイルを/app/以下にコピーしてくればそちらを優先して見ますので、必要があればコピーしたものに手を加えます。
以下よく触る順番です。
/app/controllers プログラム
/app/views HTMLテンプレート とりあえずこの2つが無いと何も表示されません。
/app/models DBとバリデーション DBの読み書きが有る場合。
/app/webroot ブラウザから見える領域です。デザイン素材とかcssとかjsはここに置きます。
/app/config 基本設定 変わったことをしなければ最初に触るだけです。
/app/vendors cake以外のプログラムを取り込むときなどはここに置きます。

■データーベース
テーブル名は英単語の複数形にする必要があります。
自分のシークエンス番号の名前は id 。
別テーブルと関連付けられているシークエンス番号は、対象テーブルの英単語名を単数形にしたもの+id。(リレーション設定時に自動検出してくれます)
作成時間は created 。(自動更新してくれます)
更新時間は updated 。(自動更新してくれます)
名前は name 。(自動で太字にしてくれたりします)
タイトルは title 。(自動で太字にしてくれたりします)

■データベースを使わない、DBを使わない
var $uses = null;

■デザインの変更
/app/views/コントローラー名/ 各ページの中心部分
/app/views/layouts/ 共通で使用する枠。
/webroot/css/ スタイルシート

■デザインの変更
以下を
/cake/console/libs/templates/skel/views/layouts/default.ctp:
以下にコピーして変更すると上書きされます。
/app/views/layouts/default.ctp:

■トップページを変更する。
以下のディレクトリとファイルを作って置きます。
/app/views/pages/home.ctp

■ビューでモデルを呼ぶ
<?php
App::import('Model', 'Shop');
$shp = new Shop();
e($form->input('shop_id',array('options'=>$shp->selectbox())));
?>

■ページネイト
1ページに表示されるレコード数
$this->paginate = array(
  'limit' => 6,
  'conditions' => array(
   'status' => 1
  )
);
$this->set('tablenames', $this->paginate());

■ページネイト
<p>
<?php echo $paginator->prev('<< '.__('previous', true), array(), null, array('class'=>'disabled'));?>
<?php echo $paginator->numbers();?>
<?php echo $paginator->next(__('next', true).' >>', array(), null, array('class' => 'disabled'));?>
</p>

<?php
if($paginator->numbers()){
$pagenum=preg_replace('/\|/','',$paginator->numbers());
$pagenum=preg_replace('/<span>/','<li class="left">',$pagenum);
$pagenum=preg_replace('/<\/span>/','</li>',$pagenum);
$pagenum=preg_replace('<span class="current">','<li class="left firstChild">',$pagenum);
e($pagenum);
}
?>

■ページネイトした後のパラム
こんなのが付いてきますのでオリジナルのページャーを作ることも可能です。
    [paging] => Array
        (
            [Album] => Array
                (
                    [page] => 2
                    [current] => 12
                    [count] => 2358
                    [prevPage] => 1
                    [nextPage] => 1
                    [pageCount] => 197
                    [defaults] => Array
                        (
                            [limit] => 12
                            [step] => 1
                            [order] => Array
                                (
                                    [id] => desc
                                )

                            [conditions] => Array
                                (
                                )

                        )

                    [options] => Array
                        (
                            [page] => 2
                            [limit] => 12
                            [order] => Array
                                (
                                    [id] => desc
                                )

                            [conditions] => Array
                                (
                                )

                        )

                )

        )


■ページネイトに条件
public $paginate = array(
 'MyModel' => array('limit' => 20,
 'order' => array('week' => 'desc'),
 'group' => array('week', 'home_team_id', 'away_team_id'))
);

■ページネイトに他のデーターを付加
// ページネイト
$conditions = array("Hoge.id" => $hoges, "portal_show_flg" => 1, "Hoge.del_flg" => 0);
$hogelist = $this->paginate('Hoge',$conditions);
// ページネイトしたデーターに他のデーターを付加
$i=0;
foreach ($hogelist as $val) {
 $res = $this->Fuga->find('first', array('conditions'=>array('hoge_id'=>$val['Hoge']['id']), 'order'=>array('order_no')));
 $hogelist[$i]['Fuga']['large'] = $res['Fuga']['large'];
 $i++;
}
$this->set('hoges', $hogelist);
$this->render('hoge_result');

■ページネイトの数を指定
<?php
if($paginator->numbers()){
$options = array('modulus'=>7); 
$pagenum=preg_replace('/\|/','',$paginator->numbers($options));
$pagenum=preg_replace('/span/','li',$pagenum);
$pagenum=preg_replace('/current/','selected',$pagenum);
e($pagenum);
}
?>

■ページネイト時のパラメーター値
GETはビューに以下を書きます。
$paginator->options(array('url' => 
    array('?' => array('kind' => '2'))
));

■モデルとコントローラーとビュー
hogesというデーターベースに対する処理を行う一連のセットは基本的に以下になります。
【モデル(対象のDBとバリデーションの設定)】/app/models/hoge.php、
【コントローラー(プログラム(或いは各処理へのリンク集))】/app/controller/hoges_controller.php、
【ビュー(HTMLテンプレート)】/app/views/hoges/index.ctp等
モデルのファイル名だけ単数形です。

■モデルの紐付け
エントリーにひもづくカテゴリーを1つ一緒にひっぱってくる。
<?php
class Entry extends AppModel {
 var $name = 'Entry';
 var $belongsTo = array(
  'EntryCategory' => array(
   'className' => 'EntryCategory',
   'foreignKey' => 'entry_category_id',
   'conditions' => array('EntryCategory.del_flg' => 0),
   'fields' => '',
   'order' => ''
  )
 );
}
?>
↑の相方で、この場合、カテゴリーにひもづくエントリーを無数にひっぱってきます。
<?php
class EntryCategory extends AppModel {
 var $name = 'EntryCategory';
 var $hasMany = array(
  'Entry' => array(
   'className' => 'Entry',
   'foreignKey' => 'entry_category_id',
   'dependent' => false,
   'conditions' => '',
   'fields' => '',
   'order' => '',
   'limit' => '',
   'offset' => '',
   'exclusive' => '',
   'finderQuery' => '',
   'counterQuery' => ''
  )
 );
}
?>

■リダイレクト
$this->redirect('/orders/confirm');
$this->redirect('/orders/thanks'));
$this->redirect('http://www.example.com');
$this->redirect(array('action' => 'edit', $id));
$this->redirect($this->referer());

■リンク
$html->link('リンク先の名前', '/pages/hoge')
<?=$html->link('hoge', '/ddd/eee.html' array('piyo' => 123)) ?>
http://aaa.co.jp/bbb/ccc/
<a href="/bbb/ccc/ddd/eee.html" piyo="123">hoge</a>

■ルートディレクトリ
以下になります。ブラウザから見えるところです。
/app/webroot/

■下の階層でセットしたセッションが上の階層で見えない
/data/hoge/cake/libs/session.php
// ひとまずここに書けば確実ですが推奨できません。
ini_set('session.cookie_path', '/');
ini_set('session.cookie_lifetime', 0);
ini_set('session.cookie_domain', 'hoge.net');

■可変長任意のURL
通常の階層構造を持ったようなURLにしたい。
下記の『■複数のアプリを配下に付ける』と似たような感じで、ウェブルートに任意のデ
ィレクトリ構造を作成し、index.phpと.htaccessを置くだけで実現可能です。
階層構造自体が引数になる場合は$_SERVER['REQUEST_URI']を解析する部品を作って噛ま
せてやれば良いと思います。

■定数の作り方
色々あると思いますが、一箇所にまとめたかったので以下になります。
/home/hoge/app/config/bootstrap.phpに以下の一行を書きます。
config('const');
/home/hoge/app/config/const.phpを作って以下のような感じに書きます。
<?php
  define("IMGURL", "http://img.hoge.tes/");
  define("IMGDIR", "/home/hoge_img/public_html/");
?>

■複数のアプリを配下に付ける
SSL申請料を節約する為にワンドメインで運用することとします。
なので、親アプリの配下に子アプリを複数設置します。
親のアプリ(hoge)
 ウェブルート → /home/hoge/app/webroot/
 アプリ → /home/hoge/app
 cake → /home/hoge/cake
子のアプリ(hage)
 ウェブルート → /home/hoge/app/webroot/hage
 アプリ → /home/hoge/app_hage
 cake → /home/hoge/cake(親のと共用)
 修正箇所
 子のウェブルートにあるindex.phpに以下の修正。
 if (!defined('ROOT')) {
//----------------------------------------------------------------------change
//  define('ROOT', dirname(dirname(dirname(__FILE__))));
  define('ROOT', DS.'home'.DS.'hoge');
 }
/**
 * The actual directory name for the "app".
 *
 */
 if (!defined('APP_DIR')) {
//----------------------------------------------------------------------change
//  define('APP_DIR', basename(dirname(dirname(__FILE__))));
  define ('APP_DIR', 'app_hage');
 }
/**
 * The absolute path to the "cake" directory, WITHOUT a trailing DS.
 *
 */
 if (!defined('CAKE_CORE_INCLUDE_PATH')) {
//----------------------------------------------------------------------change
//  define('CAKE_CORE_INCLUDE_PATH', ROOT);
  define('CAKE_CORE_INCLUDE_PATH', DS.'home'.DS.'hoge');
 }


ウェブアクセスは hoge/hage になります。
各リンクは "/controller/action" 等とすると、ドメイン直下のところに飛んでしまうので、相対パスにするか、
"/hoge/controller/action" とするか、定数を作って
"/<?php e(HOGE) ?>/controller/action" としてください。
cssやjsがおかしくならないのは、CakePHPのヘルパーを使って指定しているからだろう。
フォームもヘルパーを使っているところは何もしなくても期待通りのリンクになっています。

■超簡単に作るとき
cd ルート/cake/console
./cake bake
M
エンター → DBの数字 → n → n → y → n
C
DBの数字 → n → y → n → y → n
V
DBの数字 → y → n
Q
/app/以下にファイルが出来るので必要なら任意の場所にmv

SiteAlexa RankColorsCategoriesTagsRatingsRSS
www.cssbeauty.com10,432NoYesYesNoUrl
www.cssdrive.com14,303NoYesYesYesThumbnail
www.stylegala.com15,819NoNoNoYesThumbnail
www.cssmania.com22,686YesYesNoYesThumbnail
www.cssremix.com23,294NoNoNoYesFull Image
www.alvit.de/css-showcase/26,557NoYesNoNoUrl
www.cssvault.com27,285NoNoNoYesThumbnail
www.w3csites.com28,078NoNoNoNoUrl
www.bestwebgallery.com30,382NoYesNoNoThumbnail
www.csselite.com33,948NoYesNoNoThumbnail
www.screenalicious.com36,114YesNoNoYesThumbnail
www.unmatchedstyle.com42,269NoYesYesYesFull Image
www.designlinkdatabase.net48,086YesYesYesYesThumbnail
www.screenfluent.com51,014NoNoNoNoThumbnail
www.designsnack.com51,904NoYesNoYesUrl
www.cssheaven.com53,491NoYesNoYesThumbnail
www.cssimport.com57,960NoNoNoYesThumbnail
www.cssglobe.com65,660NoNoNoNoUrl
www.cssreboot.com67,768NoNoYesYesUrl
www.mostinspired.com68,025NoNoNoNoThumbnail
www.thebestdesigns.com68,614NoYesYesNoNo
http://thesis.veracon.net76,844NoNoNoNoThumbnail
www.cssbloom.com79,672YesYesYesYesThumbnail
www.csscollection.com92,579     
www.csstux.com98,129NoNoNoNoNo
www.cssbased.com101,834NoYesYesYesUrl
www.css-website.com102,923YesYesYesYesThumbnail
www.designshack.co.uk109,656NoNoNoNoThumbnail
www.ceeses.com124,001NoNoNoYesUrl
http://anjo.dekiteharu.jp135,146NoYesNoNoNo
www.cssclip.com135,730YesYesYesYesUrl
www.my3w.org151,235NoYesYesYesThumbnail
www.csshazard.com167,525NoYesYesNoFull Image
www.artnetz.de173,234NoYesYesNoThumbnail
www.css-design-yorkshire.com177,077NoNoNoNoNo
www.css11.com182,520NoNoYesYesNo
www.cssimpress.com188,219NoYesYesYesThumbnail
www.e-motionaldesign.com202,826NoYesNoYesThumbnail
www.cssprincess.com210,811NoYesYesYesNo
www.cssgaleri.com220,224NoYesNoNoThumbnail
www.cssblast.ru224,048NoNoNoNoUrl
www.creative-pakistan.com233,247NoYesNoYesThumbnail
www.netzfruehling.de237,645NoNoNoNoNo
www.najdizajn.com256,885NoYesNoYesThumbnail
www.edustyle.net274,750NoNoNoYesNo
www.csssmoothoperator.com290,827NoNoNoNoThumbnail
www.coolsitecollection.com313,655NoYesNoNoThumbnail
www.cssgalaxy.com348,352NoYesNoNoThumbnail
www.per.fectio.net357,030NoNoNoYesNo
www.cssflavor.com364,755NoNoNoNoThumbnail
www.onepixelarmy.com369,312NoYesNoNoUrl
www.piepmatzel.de418,803NoNoNoNoUrl
www.cssbrain.hu438,074NoYesNoNoThumbnail
www.w3c-compliance.com461,674NoNoNoNoNo
www.stylegrind.com484,645NoNoNoNoUrl
www.submitcss.com523,147     
http://inspirace.dobrestranky.com549,529NoYesYesYesFull Image
www.cssgallery.ro553,463NoYesNoYesUrl
www.cssgreen.com600,815NoYesNoNoNo
www.csszengarden.com13,878NoNoNoNoUrl
www.webcreme.com21,564YesNoNoNoThumbnail
www.prowebart.net324,625NoYesYesNoFull Image
www.designexpanse.com340,762NoYesYesYesThumbnail
www.csssnap.com360,300NoYesNoYesThumbnail
www.menthe-fresh.fr427,757YesNoNoYesThumbnail
www.csscoosite.com548,693NoYesYesYesUrl
www.csscool.cn681,511NoYesYesNoThumbnail
www.morpheed.com/css2,313,992NoNoNoNoThumbnail
www.csstown.com3,463,368NoNoNoYesNo
aquacreate+web:webデザイン集

Adobe Air はどうなったんだ、って言われそうなんだけど、FlashSC4買ったらそのままAir形式で保存とかできたので、それまでFlashを使えていれば新しく覚えることは無いじゃんか、ってことでテンション下がりましたとさ。

で、タダで500MBも使えるレンタルサーバーがあるって聞いたんで使ってみようそうしようということになりました。
その名は『Google App Engine』
これは具体的に何かっていうと、Googleが「タダでうちのサーバー使っていいよ、データベースもね、おまけにローカルで動く開発環境も持ってけドロボー」って言うもんだから猫もしゃくしも使え使えってなっているものなんだ。
ロリポップも真っ青。
ちょうど負荷の高くなりそうな個人サービスをしたくなっていたところなので調度良かったよ。

ただ、普通のレンタルサーバーみたいにFTPでアップしたら終わりってもんじゃなくて、Google独自の形式に則って書いたりアップしたりしないといけないんだ。
というわけで、以下に開発環境の手順を記します、って思ったんだけど、Googleのチュートリアルがあまりにも丁寧なので書くことありませんw。

ちょっと本屋で関連書籍立ち読みしたんだけど、ほんとにネットのチュートリアルで足りる感じです。
あとは、難しいことするんだったら専用言語のPython(パイソン)か最近使えるようになったJAVAに慣れないといけないんだけど、ここで言語の講座をまるまるするのも不可能なので他所でお願いするとして、さて何を書きましょうかね。

では補足というかメモみたいなものを。

■google_appengine/dev_appserver.py helloworld/ ってしたのに表示しない。
環境にも寄りますが、私の場合以下のような感じでした
ディレクトリの場所
C:\Program Files\Google\helloworld/
正解
cd C:\Program Files\Google\
dev_appserver.py helloworld/
http://localhost:8080/
もしパスが通って無かったら以下みたいな感じですかね
cd C:\Program Files\Google\google_appengine
dev_appserver.py ../helloworld/

■環境設定したのにパスが通らない。
windows 7 なのですが、いろいろ試した結果、後ろではなく前に描き足したらいけました。

■mod rewriteちっくにURLを引数にしたい
()でくくると行けました。具体的には以下のような感じ。
application = webapp.WSGIApplication(
         [('/(.*)/(.*)', MainPage)],
         debug=True)
受ける方はこう
class MainPage(webapp.RequestHandler):
  def get(self, val1, val2):
  ?

■Googleアカウント無い人のログインチェックは?
自分で作るよろし。

う?ん、またカテゴリーつくって書き足してゆくかな。
そのときは Google App Engine にしたらよいのか Python にしたらよいのか、どうしよう。(-_-)

■全角空白で壺った
メール本文の全角スペースとかを消したかったんだけど、以下。
ISO-2022-JPではなくSJISにしていた。_ノ乙(、ン、)_
$diary_body = mb_convert_encoding($diary_body, "UTF-8", "ISO-2022-JP");
$chkName = $diary_body;
$chkName = preg_replace('/ |\s|\t|\n|\r|\0|\x0B/u', '', $chkName);

■postfixから外部に送信できない
以下のようなエラーが出る場合。
Connection timed out (port 25)
さんざん悩んだ結果。さくらVPSでは仮登録中にメール送信できません。
いくら調べても分からないわけだw。
お金振り込んでもらったら難なく動いた。

■ムームーDNSカスタム設定からロリポップを指定する方法
ムームーDNSカスタム設定してしまったドメインに後からロリポップを追加するには以下の手順。
1)(ムームー管理画面)カスタム設定を解除
2)(ムームー管理画面)ロリポップDNSに変更
3)(ロリポップ管理画面)ドメインやサブドメインの設定
4)(ムームー管理画面)ムームーDNSに設定
5)(ロリポップ管理画面)ムームーDNSに移行
6)(ムームー管理画面)再びカスタム設定を設定
 ※ 3) で設定したサブドメイン等が 6) で選択可能に。
 ※DNSの切り替えに1時間程度かかるのでその間はサイトが見えない。
 ※カスタム設定の内容が全部消えてしまうので入力し直し+テスト。

■ワイヤーフレームを作ってくれるブックマークレット
↓を見ているサイトのURL欄に貼ります。
javascript:(function(){wf_bookmarklet={ver:'1.5',ka:86400000,to:7000};if(typeof%20wfInit=='undefined'){var%20s=document.body.appendChild(document.createElement('script')).src=(document.location.protocol=='https:'?'https:':'http:')+'//www.wirify.com/client/wirify.min.js?'+parseInt(new%20Date().getTime()/wf_bookmarklet.ka);window.setTimeout(function(){if(typeof%20wfInit=='undefined'){alert('Wirify%20is%20still%20processing%20or%20temporarily%20unavailable,%20please%20try%20again%20in%20a%20moment\n\nVisit%20%20twitter.com/wirify%20%20and%20%20www.wirify.com/blog%20%20for%20latest%20announcements');}},wf_bookmarklet.to);}else{wfInit();}})();

■ロリポップのウェブメールにある「送信済みメール」を取り出す方法
メールサーバーを引っ越ししようと思って調べたのだけれども。
パソコンのメーラーから送信した分は、ウェブメールの「Sent」で同期がとれていますが、ウェブメールから送信した分の「送信済みメール」は同期がとれていません。
今までウェブメールから送信した文を取り出したいのだけどどうしても方法が分からない。
なので、ロリポップにメールで質問しました。そしたら。
「その方法はありません」
とのこと。
_ノ乙(、ン、)_
一通一通コピペするか転送するしかないのか......

■ムームードメインから自前のサーバーに設定
1) ムームードメインログイン
2) 任意のドメイン→詳細→表示する
3) ムームーDNS→セットアップ(カスタム設定にしておく)
4) 例)↓な感じ
20110425.png
※ぼやけてるところはIPアドレス。MXの指定でけっこうハマった。

■Google検索のリミッター解除
http://www.google.co.jp/setprefs?submit2=%E4%BF%9D%E5%AD%98+&hl=ja?=all&num=10&q=&prev=http%3A%2F%2Fwww.google.co.jp%2F&safe=off

■今まで見聞きしたサーバーがダウンする感じの現象
例(1)アクセスが異常発生。
対処(1-1)特定のIPからのアクセスを禁止する。
対処(1-2)どうしようかと考えているうちにアクセスが止んで復旧。

例(2)閲覧できるけど更新できない。
対処(2-1)アクセス解析用のデーターが溜まりまくってハードディスクの容量を使い切っていた。
要らないデーターを削除&溜まらないような仕組みに変更。

例(3)アクセスが増えるとダウン。
対処(3-1)メモリを喰い過ぎているのが分かったのでメモリを増やす。
対処(3-2)根本的にはDBのクエリで遅いものがあり、プロセスが山のように溜まり、その1個1個のプロセスがメモリを食いつぶしていたのが分かった。
SQL文の見直し等を行う。
応急処置:ある程度プロセスが溜まってメモリが無くなってきたらDB再起動。(良くは無いけどダウンよりはマシということから)

例(4)メール配信が止まった
対処(4-1)スパムメールに対しても全部エラーメールを返していたために固まっていた。エラーメールは返さないようにした。(本当の打ち間違いに対しても返せなくなるので、このポリシーは状況によって判断すべき)

■リストア(OS9)
ノートンでディスクチェックしていたらフリーズしたのでどうしようもなくなって電源長押しで再起動。
再起動できなくなった。
CD起動(cを押し続けながら電源ON)してハードディスク確認すると使用不能。(-_-;
ノートン先生大爆発。
ハードディスクはマウントする為にとりあえず初期化。
被害は最小限に抑えるため、その状態で補完。後は修復ツール頼みとしよう。
新しいハードディスクを買ってくる。
ハードディスクの裏に書いてある図を見てコネクタをマスターに切り替える。
ひとまず旧ハードディスクから線を抜いて(激堅)新ハードディスクに刺してみる。
リストアCDからCD起動。
ユーティリティーのドライブ設定からハードディスクを認識してマウント。
これにOS9をインストール。
終わったら再起動&設定。
ハードディスクから起動出来たのを確認出来たのでシステム終了。
ハードディスク置き場を整理。
また線を抜く(激堅)。
手前中央にあるネジを一本抜く。
台座ごと少し手前にズらして外す。
横のネジを外す。
買ってきた方を下に、もとのやつを上にしてネジで止める。
ネジがなかったのでもとの4本を2本ずつ分けて使う。
ここで問題。
旧ハードディスクにはジャックピンの説明図が無い。
ググってこんな画像を見つけたけど該当のが無いような。
3050-1.gif
3050-3.jpg
なぜなら、もともとのやつはマスターで
135 8
24679
のピンの1-2と3-5にコネクタが付いていたのだ。
しかし、おそらく3-5は意味がないものだと考え、全外しか3-4の2択というかどっちでも良い感じなので、部品を捨てるのももったいないから3-4に刺して再起動。
ドライブ設定で見るとマスターが0、今のが1になって認識できていたのでオッケー。
これでひとまずマシン自体は復旧出来た。
あとはスレイブになった旧ハードディスクからどれだけデーターを救出できるか。
以上。

■CD起動が出来ない(OS9)
同じOS9のCDに見えても、購入時そのマシンに付属していたCDでないと出来ない場合がある。
(別途中古で買ったMac付属のCDで死ぬ程失敗したけど差替えたら一発で起動した)

■コピーの仕方
ローカルでコマンド。
これは下記「トンネルの仕方」をした状態でサーバーからローカルにコピーする例。
scp -r hostname2:/var/www/user/local/ ./

■トンネルの仕方
/Users/username/.ssh/config
に以下を記述

Host *
ForwardAgent yes
GSSAPIAuthentication no

Host hostname1
User root
Hostname 111.111.111.111

Host hostname2
User root
Hostname 222.222.222.222
ProxyCommand ssh hostname1 nc %h %p

/Users/username/.ssh/
にキーを置く

サーバーの.sshにもこっちのキーを書き足しておく。

ssh hostname2

■ターミナルの開き方
Mac HDD → アプリケーション1 → ユーティリティー → ターミナル

javaのjdkをインストール
% sudo apt-get install openjdk-6-jdk
% sudo apt-get install sun-java6-jdk

デフォルトで使用される JDK を選択してみます。openjdk-6-jdk と sun-java6-jdk をインストールした状態ではまだ OpenJDK が使われているので、
% which java
/usr/bin/java
% java -version
java version "1.6.0"
OpenJDK Runtime Environment (build 1.6.0-b09)
OpenJDK Client VM (build 1.6.0-b09, mixed mode, sharing)
%

以下で、/usr/lib/jvm/java-6-sun/jre/bin/java を選択する。
java-6-sun をデフォルトに設定してみます。
% sudo /usr/sbin/update-alternatives --config java
選択肢 alternative
-----------------------------------------------
*+ 1 /usr/lib/jvm/java-6-openjdk/jre/bin/java
2 /usr/lib/jvm/java-6-sun/jre/bin/java

デフォルト[*] のままにするには Enter、さもなければ選択肢の番号のキーを押してください: 2
Using '/usr/lib/jvm/java-6-sun/jre/bin/java' to provide 'java'.
%
% java -version
Java(TM) SE Runtime Environment (build 1.6.0_06-b02)
Java HotSpot(TM) Client VM (build 10.0-b22, mixed mode, sharing)
%

eclipseのコンフィグに以下を追加
vim /etc/eclipse/java_home
/usr/lib/jvm/java-6-sun/ をいちばん上に追加

eclipseのプロジェクト→プロパティーでEUC-JPを選択。

なにとなくLinuxをインストールするとapxsが入ってないことが多い。
yum install httpd-devel,up2date instal httpd-devel,aptitude apache-develなどで入る場合は良いけど、そうでないこともある。
というわけでApacheをソースからインストール。

1) <a href="http://www.apache.jp/misc/download.html">apacheのサイト</a>からhttpd-2.2.11.tar.gzとかをダウンロード。
tar zxf httpd-2.2.11.tar.gz
解凍したらその中にはいって以下

./configure --enable-modules=all --disable-dav --enable-so --with-ssl --enable-rewrite --enable-mods-shared=all
make
make install

64bitのLinuxだったら --with-expat=builtin を追加
 ./configure --enable-modules=all --disable-dav --enable-so --with-ssl --enable-rewrite --enable-mods-shared=all --with-expat=builtin
make
make install

※./configure でエラーになるときは、Linuxのインストール時にcのコンパイラが入ってない時が多い、インストールし直しで、インストール内容をカスタマイズして開発を選択するように。

/etc/init.d/httpd の中を新しいほうに書き換える。
apachectl=/usr/local/apache2/bin/apachectl
httpd=${HTTPD-/usr/local/apache2/bin/httpd}

今までの場所を使いたいんだったら、昔のやつは名前を変えてとっておいて、以下のようなシンボリックリンクを作るなり何なり。
ln -s /etc/httpd/conf /usr/local/apache2/conf
ln -s /var/log/httpd /usr/local/apache2/logs
ln -s /usr/bin/modules /usr/local/apache2/bin/modules

httpd.confのLoadModuleあたりも漏れなく書き直すと無難。

ちょっと複数のLinux環境でオリジナルのアパッチモジュールをコンパイルをする用事があったのでメモ。
というわけで、てきとーなマシンにLinuxをいれてVMWareServerをいれてそのなかに他のLinuxをいれるとす。
土台は Fedora Core 10。redhatに近いのでクライアントのサーバーに行った時にとまどわなくてすむ。と思う。
Fedora Core 10
Firefox3

■準備

Fedora Core 10 は本屋で日経Linuxを買ってきてふろくのDVDからインストール。
めんどくさいのでSELinuxとファイヤーウォールは無効。セキュリティはルータに任せておこう。
VMwareのサイトで会員登録してダウンロード。
このときのシリアルを後で使います。
http://www.vmware.com/download/server/
http://register.vmware.com/content/registration.html

Fedora Core 10 でrootログインできるようにする。
以下ファイルの該当箇所をコメントアウトする。
/etc/pam.d/gdm
#auth required pam_succeed_if.so user != root quiet

rootでログインする。
(rootでログインしないと後でブラウザからアクセスできない)

Fedora Core 10 でアパッチの起動。
なんとかマネージャーみたいなのはオフ。
システム→管理→サービス→httpd

■VMWareServerを使う

VMWare Server に必要な xinetd をインストール。
yum -y install xinetd
/etc/rc.d/init.d/xinetd start
chkconfig xinetd on

VMWare Server をインストール。
rpm -Uvh VMware-server-2.0.1-156745.i386
/usr/bin/vmware-config.pl
全部「y」かデフォルト値。
準備で得たシリアルを入力。

ブラウザでアクセス。
https://localhost:8333/
root/rootのパスワード
httpsだからFireFox3で警告が出ますが例外扱いにしてスルー。
というか、このへんで1回繋がらなかったので再起動したら繋がった。

右上の「Create Virtual Machine」をクリック。
Name:に任意の名前を入力して「Next」。
インストールするOSの種類を選んで「Next」。
割り当てるRAMのサイズと、CPUのコア数を選択して「Next」。
「Create a New Virtual Disk」を選択して「Next」。
容量などを設定して「Next」。
「Add a Network Adapter」を設定して「Next」。
つなぐネットワーク(デフォルトはNAT)を選択して「Next」。
インストール方法を選択して「Next」。
 DVDやCDなら「Use a Physical Drive」。
 ダウンロードしたファイルからなら「Use an ISO Image」。
上で分岐しますが、ドライブやファイルを指定します。
Floppy Drive は無かったので「Don't Add a Floppy Drive」を選択して「Next」。
USBは一応「Add a USB Controller」選択して「Next」。
「Finish」して設定完了。

左端の「Inventory」から今のをクリック。
画面上中央の再生ボタンをクリックすると、右の「Status/Power Status」が「Powered On」に。
再生ボタン下の「Console」をクリック。
初回は「Install plug-in」をクリック。
許可してアドオンをインストール。再起動。
画面が真っ白。
理由は分からないけどアドオンを無効にしたり有効にしたりしているうちに表示されるようになった。
謎。表示された時のURLは「https://localhost:8333/ui/#」。
気を取り直して左端の「Inventory」から今のをクリック。
画面上中央の再生ボタンをクリックすると、右の「Status/Power Status」が「Powered On」に。
再生ボタン下の「Console」をクリック。
「Open the console in a new window.」画面をクリックすると仮想窓が開くので、その前にOSのDVD等を入れておいてインストール。
カーソルが窓の中にとりこまれるので、こっちに戻すには「Ctrl+Alt」。
なんでかしらんけど、アンダーバーが入力できない。そのつどコピペして対応。とてつもなく不便。アンダーバー様の偉大さを思い知る。アンダーバーを笑うものはアンダーバーに泣く。

Adobe AIR アプリのアンインストール方法

Windows だと普通に「スタート→コントロールパネル→プログラムの追加と削除」でできるんだけど、Ubuntu(Linux)ではどうすんの、ってちょっと迷ったので記すことにしようそうしよう。

root@masumoto-desktop:/opt# dpkg -S /opt/*
adobeair1.0: /opt/Adobe AIR
com.adobe.example.passwdgc.a6ba28f144513ff9214613f74810fd6452bda18a.1: /opt/passwdGC
root@masumoto-desktop:/opt# dpkg -P com.adobe.example.passwdgc.a6ba28f144513ff9214613
f74810fd6452bda18a.1

(データベースを読み込んでいます ... 現在 110270 個のファイルとディレクトリがインストールされています。)
com.adobe.example.passwdgc.a6ba28f144513ff9214613f74810fd6452bda18a.1 を削除しています ...
root@masumoto-desktop:/opt#

アプリじゃなくて本体のほうはGUIの アプリケーション→アクセサリ→Adobe AIR Uninstaller でいけるよ。
いじょ。今日はここまで。