ボタンジェネレーター  CSS Button Generator  ジフローダージェネレーター  リントチェッカー  Another HTML-lint 5
いけてるサイト  WEBデザインの見本帳  ビジネス文例集  CakePHP規約ワードメーカー  ファビコン作成  ブラウザ検証
flaデーター(Movies→Games→Full_Game_Source)  カラーチャート  グラデーションジェネレーター  シャドウジェネレーター

CakePHP2.3

■ModelとHelperと日本語化ファイルを異なるappで共有
app_user から app の中を参照する例。
App::build(array(
  'Model' => array(ROOT.DS.'app'.DS.'Model'.DS),
  'View/Helper' => array(ROOT.DS.'app'.DS.'View'.DS.'Helper'.DS),
  'Locale' => array(ROOT.DS.'app'.DS.'Locale'.DS),
));
ln -s でも良いけど、引っ越しすることを想定すると極力シンボリックリンクは少ない方が良いので。

■モデルから他のモデル、Modelから他のModel
App::import('Model','Product');
$Product= new Product;
$Product->find('all');

■ページネートと検索
迷走中だけどとりあえずメモ。
条件をセッションに覚えさせておき、新たに条件が入ってきたら上書きします。
検索条件+タブ(有効・無効・ぜんぶ、とか、既読・未読・全部、等)を想定しています。
・その1
コントローラー(タブのみ)
  public function index() {
    $this->OrderHeader->recursive = 0;
//    $this->set('orderHeaders', $this->paginate());

    // 検索条件セット
    $setCconditions = $this->getCconditions('OrderHeader', null, null, 'status');
    // 返り血に選択済みタブがあればセット&オプションから削除
    $selectedStatus = '0';
    if(isset($setCconditions['tab'])){
      $selectedStatus = $setCconditions['tab'];
      unset($setCconditions['tab']);
    }
    $this->set('selectedStatus', $selectedStatus);
    $this->paginate = $setCconditions;
    $res = $this->paginate();
    $this->set('orderHeaders', $res);
  }

ビュー(タブ)
<div class="orderHeaders index">
  <h2><?php echo __('Order Headers'); ?></h2>
  <?php echo $this->element('statuspaginate'); ?>
?

エレメント(タブ)
statuspaginate.ctp
<?php
  if(!empty($status)){
    $paginator->options(array('url' => array('?' => array('status' => $status))));
  }
?>
<div class="status">
  <div style="float: right;">
    <?php   echo $this->Paginator->counter(array('format' => __('Page {:page} / {:pages}, ( {:start} - {:end} / {:count} )'))); ?>
  </div>
  <div style="float: left;">
    <?php echo (isset($selectedStatus)and($selectedStatus===0))?'<span style="color: #F00;">有効</span>' :$this->Html->link('有効', array('action' => 'index?status=0')); ?> 
    <?php echo (isset($selectedStatus)and($selectedStatus==='1'))?'<span style="color: #F00;">無効</span>' :$this->Html->link('無効', array('action' => 'index?status=1')); ?> 
    <?php echo (isset($selectedStatus)and($selectedStatus==='allstatus'))?'<span style="color: #F00;">全部</span>' :$this->Html->link('全部', array('action' => 'index?status=allstatus')); ?> 
  </div>
</div>

・その2
コントローラー(検索有り)
  public function index() {
    // 検索条件セット
    $setCconditions = $this->getCconditions('OrderHeader', null, null, 'status');
    if(!empty($setCconditions['data'])){
      $this->data = $setCconditions['data'];
    }
    // このページ独自のルールに成型
    if(!empty($setCconditions['conditions']['OrderHeader.date'])){
      $setCconditions['conditions']['OrderHeader.date LIKE'] = '%'.$setCconditions['conditions']['OrderHeader.date'].'%';
    }
    if(isset($setCconditions['conditions']['OrderHeader.date'])){
      unset($setCconditions['conditions']['OrderHeader.date']);
    }
    $this->OrderHeader->recursive = 0;
    $this->paginate = $setCconditions;
    $this->set('orderHeaders', $this->paginate());
  }

ビュー(検索)
<div class="orders index">
  <h2><?php echo __('Orders'); ?></h2>
<div>
<?php
  echo $this->Form->create('OrderHeader');
  echo $this->Form->input('level_id', $this->Html->selectLevels((isset($this->request->data['OrderHeader']['level_id']))?$this->request->data['OrderHeader']['level_id']:1));
  echo $this->Form->input('date');
  echo $this->Form->input('status', array('type'=>'hidden', 'value'=>'0'));
  echo $this->Form->end(__('Submit'));
?>
</div>
?

・その1、その2共通
AppController.php
  function getCconditions($model=null, $data=null, $params=null, $tabname=null) {

    $tab = 0; // ★デフォの status を 0 とします
    $all = 'allstatus'; // ★status条件エスケープ文字を allstatus とします
    $limit = 10; // ★表示数

    // セッション呼び出し
    $searchItems = $this->Session->read('searchItems');
    $searchItems = (empty($searchItems[$model]))?'':$searchItems[$model];

    // 入力値セット
    // 明示的に指定されていればそちらを優先
    // ($data があれば $data, 無ければ $this->request->data, 両方なら $data)
    $data = ((empty($data))and(!empty($this->request->data))) ?$this->request->data :$data;
    $params = ((empty($params))and(!empty($this->params))) ?$this->params :$params;
    // $this->request->data ハッシュで受け取ります
    // passの場合 ex.)/index/status/1/page/2 配列で受け取ります
    $pass = $params->params['pass'] ?$params->params['pass'] :'';
    // namedの場合 ex.) /index/status:1/page:2 ハッシュで受け取ります
    $named = $params->params['named'] ?$params->params['named'] :'';
    // queryの場合 ex.)/index?status=1&page=2 ハッシュで受け取ります
    $query = $params->query ?$params->query :'';

    // 入力値があれば上書き
    if((!empty($data[$model]))or(!empty($pass))or(!empty($named))or(!empty($query))){

      // 全ての入力値をハッシュ化 【http → $items】
      $items = array();
      if(!empty($data[$model])){
        $items = $data[$model];
      }
      // 混在していてもカバーできるよう elseif を使わない
      if(!empty($pass)){
        foreach($pass as $key => $val){if($key % 2 != 1){$items[$val] = $pass[$key+1];}}
      }
      if(!empty($named)){
        foreach($named as $key => $val){$items[$key] = $val;}
      }
      if(!empty($query)){
        foreach($query as $key => $val){$items[$key] = $val;}
      }

      // タブはstatusの値。明示的にタブ名が指定されていればそちらを優先。
      if(!empty($items['status'])){
        $tab = $items['status'];
      }
      if(isset($items['tabname'])){
        $tab = $items['tabname'];
      }

      // 検索項目以外を削除しつつセット 【$items → $searchItems】
//      if(isset($items['url'])){unset($items['url']);}
      // 順序
      if(isset($items['sort'])){
        $searchItems[$model][$tab]['sort'] = $items['sort'];
        unset($items['sort']);
      }
      if(isset($items['direction'])){
        $searchItems[$model][$tab]['direction'] = $items['direction'];
        unset($items['direction']);
      }
      // ページ
      if(isset($items['page'])){
        $searchItems[$model][$tab]['page'] = $items['page'];
        unset($items['page']);
      }

      // 条件だけになりました
      // 検索条件が無い場合でもセッションにあれば呼び出し(ページネート・出戻りと見なし)ます
      if(empty($items)){
        if(!empty($searchItems[$model][$tab]['data'][$model])){
          $items = $searchItems[$model][$tab]['data'][$model];
        }
      }else{
        // 検索条件有り:data以外ならクリア、dataなら入力内容復帰用に保存
        if(empty($data)){
          $searchItems[$model][$tab]['data'] = '';
        }else{
          $searchItems[$model][$tab]['data'] = $data;
        }
      }

      // 条件だけになったのでキーにモデル名を付加
      // 値がエスケープ値なら無視
      $itemsR = array();
      foreach($items as $key => $val){
        if($val != $all){$itemsR[$model.'.'.$key] = $val;}
      }
      $searchItems[$model][$tab]['conditions'] = $itemsR;

      // ページネート時にどのタブを引き継ぐかを保存
      $searchItems[$model]['selectingtab'] = $tab;

    } // 入力値があれば上書き

    // searchItems から成型 【$searchItems → $option】
    // 最低必要項目セット
    if(empty($searchItems)){
      $searchItems[$model][$tab]['conditions'] = array($model.'.status' => $tab);
      $searchItems[$model][$tab]['sort'] = 'id';
      $searchItems[$model][$tab]['direction'] = 'desc';
      $searchItems[$model]['selectingtab'] = $tab;
    }else{
      if((empty($searchItems[$model][$tab]['conditions']))and($tab != $all)){
        $searchItems[$model][$tab]['conditions'] = array($model.'.status' => $tab);
      }
      if(empty($searchItems[$model][$tab]['sort'])){$searchItems[$model][$tab]['sort'] = 'id';}
      if(empty($searchItems[$model][$tab]['direction'])){$searchItems[$model][$tab]['direction'] = 'desc';}
      $tab = $searchItems[$model]['selectingtab'];
    }

    // 順序
    $direction = (isset($searchItems[$model][$tab]['direction'])) ?$searchItems[$model][$tab]['direction'] :'';
    if((isset($searchItems[$model][$tab]['sort']))and($searchItems[$model][$tab]['sort'] != 'clear')){
      $options['order'] = $model.'.'.$searchItems[$model][$tab]['sort'].' '.$direction;
    }else{
      $options['order'] = $model.'.id DESC';
    }
    // ページ
    if(!empty($searchItems[$model][$tab]['page'])){
      $options['page'] = $searchItems[$model][$tab]['page'];
    }
    // 検索条件
    if(!empty($searchItems[$model][$tab]['conditions'])){
      $options['conditions'] = $searchItems[$model][$tab]['conditions'];
    }

    // 表示数
    $options['limit'] = $limit;

    // 選択タブ
    $options['tab'] = $tab;

    // 画面復帰用データ
    $options['data'] = (empty($searchItems[$model][$tab]['data']))?'':$searchItems[$model][$tab]['data'];

    // セッションに検索条件を保存
    if(!empty($searchItems)){
      $setSearchItems[$model] = $searchItems;
      $this->Session->write('searchItems', $setSearchItems);
    }

    return $options;
  }

■Fatal error: Class 'AppController' not found in ディレクトリ名/lib/Cake/Controller/CakeErrorController.php on line 32
AppControllerが無い、とか一瞬びびるエラーですが嘘です。
AppController.php にプログラムを記述するときには、その文章が間違っている(文末の ; が抜けてる等)だけでこのエラーがでます。

■ページネート(paginate)で有り得ないページを指定するとエラーになる
1.3とかだとエラーではなく空で返してくれてました。
基本無視して良いかと思いましたが、一覧閲覧中にデーターが変動してページが消失する事は有り得るので修正するとす。
/lib/Cake/Controller/Component/PaginatorComponent.php
237
/* エラーにしない
        if ($requestedPage > $page) {
            throw new NotFoundException();
        }
*/

CakePHP1.3

| コメント(0) | トラックバック(0)
■直前で保存したレコードのID
if($this->Hoge->save($data)){
  $new_id = $this->Hoge->getLastInsertID();
}

■ヘルパー内でインナージョイン
  $params = array(
   'conditions' => array(
    'Hoge.contractor_id' => $contractor_id,
    'Hoge.status' => 0,
   ),
   'fields' => array('id', 'Hoge_name'),
   'order' => array('id ASC'),
   'joins' => array(
    array('type' => 'INNER',
     'table' => '`Hoge_details`',
     'alias' => 'HogeDetail',
     'conditions' => '`Hoge`.`id`=`HogeDetail`.`Hoge_id`',
    ),
   ),
  );
  $HogeData = $Hoge->find('all', $params);

■全角文字を json_encode してMySQLに保存したら decode できなくなった。
save のときは良いのだけれど、 updateAll の時に発症します。
プログラムを追っていくと、updateAllの方には mysql_real_escape_string() が抜けていることが分かりました。
1) 全角文字があるときは updateAll とは別の手段で一括更新する。(queryやfind,for,save等
2) json_encode() と updateAll() の間に mysql_real_escape_string() でもかましておく。
3) 以下のファイルあたりを修正する。(やめといた方が良い)
 /cake/libs/model/datasources/datasource.php
 /cake/libs/model/datasources/dbo/dbo_mysql.php

■ajaxで組み立てたページから遷移してhistorybackで戻ったら元に戻らない(組み立て前の画面になる)
ブラウザによって挙動は異なるが基本的にダメ。
解決方法は以下。

1)historybackを使わない。
    『戻る』ボタンはサーバーに投げて、前にポストした情報を基にサーバー側で再構築し直す。
 更新に必要でなくても構築に必要なものはhiddenで送っておく。
 どんな画面でも再現できるが鬼面倒です。
2)フォームの中身はどのブラウザも復元してくれるので、その内容に基づいて再構築する。
 必要な情報はhiddenに埋めておく。
 ページ読み込み時にformの各値を呼んで反映させる。
 フォーム自体がajaxで呼ばれている場合は 1) が望ましい。
 タイムラグが影響の無い範囲ならこちらでも良い。

■フロントと管理画面を分けるとき
public_html と public_html/admin とかでindex.phpの内容かき分けるのでも良いのだけど、自分でapache触れるときは以下の方が閉鎖されて便利かもです。
ウェブルートを webroot に。
ln -s /home/www.hoge.jp/cakephp/app/webroot /home/www.hoge.jp/public_html
ln -s /home/www.hoge.jp/cakephp/app_admin/webroot /www.hoge.jp/public_html/VxBAZ5dI8cyYZn
モデルやコンストを共有するときは以下。
ln -s /home/www.hoge.jp/cakephp/app/models /home/www.hoge.jp/cakephp/app_admin/models
bootstrap.php
App::build(array(
  'models' => array(ROOT.DS.'app'.DS.'models'.DS),
));
config('../../app/config/const');

■paginateでgroupを指定するとページングの数字が消える。
$options['group'] = array('url','ymd');
$options['limit'] = 5;
$this->paginate = $options;
$this->set('url_logs', $this->paginate($conditions));
みたいなとき、ページングが消えます。
app_model.php に以下を記述します。
function paginate($conditions, $fields, $order, $limit, $page = 1, $recursive = null, $extra = array()) {
  $conditions[] ="1 = 1 GROUP BY week, away_team_id, home_team_id";
  $recursive = -1;
  $fields = array('week', 'away_team_id', 'home_team_id');
  return $this->find('all', compact('conditions', 'fields', 'order', 'limit', 'page', 'recursive'));
}

■Warning (2): strtotime() [http://php.net/function.strtotime]: It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected 'America/New_York' for 'EDT/-4.0/DST' instead [CORE/cake/libs/cache.php, line 597]

php.ini に以下を書き込んでアパッチ再起動。

date.timezone =Asia/Tokyo

■bootstrap.php に関数を書く。
便利だけどあまり見かけないので多用しない方が良いのかな。
ここに直接書いても良いですが、const.php とでも作って置いて以下の記述により呼び出し。
config('const');
例)
// 固定値
define("PAGELIMIT", 10);
// 誕生日年(固定)   
function BirthYear(){
    // minYear=最小年齢 minYear+maxYear=最高年齢
    $now = getdate();
    $data = array('minYear' => $now['year'] -4, 'maxYear' => $now['year'] -96, 'dateFormat'=>'YMD');
    return $data;
}
ビュー
echo $form->input('birthday',BirthYear());

■ちょっとしたメモ(自分流儀的な)
・メソッドは全部モデルに。なぜならどこからでも呼び出せるから。
・固定値はbootstrap.phpあたりに。
・コントローラーで処理するようなことをビュー(helper)にさせるのは有りだが、モデルのメソッドを呼ぶ踏み台程度にしたほうが良い。テンプレにプログラムを書きすぎるのは良くないです。
・共通部分はなるべくエレメントに。スマホ版にも転用できるできないで作業は2倍になります。
・(1)javascriptで、PHPから渡す変数を動的に使いたいときにはエレメントに書いて各々食わすのが良いのか、(2)あくまで固定ファイルとして置いておいて、変数はHTML内に1つ置き場を決めておき、JSONで食わす+jqueryで取り出すのが良いのか。
 ファイル呼出順が影響するものが有るかもだから(2)が良いのかな。
・$this->Model->save($this->data)←この形だと悪意によるformへの要素追加があった場合、更新できてしまうので、何かしらワンクッション置いた方が良い。
ex.1)$data['Model']['name']=$this->data['Model']['name'];
ex.2)unset($this->data['Model']['status']);

■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 → アカウントアクティビティ でときどき料金の確認をしよう。

■日本語化
cd /home/hoge/cake/console
chmod 775 cake
./cake i18n
cd /home/hoge/app/locale/
mkdir -p jpn/LC_MESSAGES
cp default.pot ./jpn\LC_MESSAGES/default.po
default.po の中に対応する文字列を記入してリロードすると変わります。
・この時点で存在しているものは上記のコマンドによりviewsを探して一覧にしてくれていますが、今後できたページに関しては、マネして書き足していけばよいです。
・いったんデバックモードにしないと書き換わらないことが多いです。

■デバックモードにしたら盛大にエラーがでる。
Strict Standards: Non-static method Debugger::invoke() should not be called statically, assuming $this from incompatible context in /home/test.hoge.com/cake/libs/debugger.php on line 566 Strict Standards: Non-static method Debugger::getInstance() should not be called statically, assuming $this from incompatible context in /home/test.hoge.com/cake/libs/debugger.php on line 566
別件で、同サーバーをPHPがらみでいろいろいじっていたら、出るようになってしまいました。
デバッグモードじゃなければ問題ないっぽいです。
cakephp1.3で動いている別アプリでは出ないです。

なんだかよくわからないけれど、Non-static method に関する通常の力技で対処。
全部のメソッドを追って行って、片っ端から前に static を付けるとす。
ex.)
function invoke(&$debugger) {

static function invoke(&$debugger) {
このあと、これに関連して次々修正するハメになりますが、debugger.phpとconfigure.php内のいくつかのメソッドを修正するとエラーが全部消えました。

■ヘルパーの作り方使い方
ビューの下にファイルを置きます。
/app/views/helpers/hoge.php
例)
<?php
class HogeHelper extends AppHelper
{
 function hoge() {
  return 'wwwww';
 }
 function hage($data=null) {
  App::import('Model', 'Hage');
  $Hage = new Hage();
  $params = array(
   'conditions' => array('status'=>0),
   'fields' => array('id', 'name'),
   'order' => array('created DESC'),
  );
  $hageData = $Hage->find('all', $params);
  $data = array();
  foreach($hageData as $val){
   $data[$val['Hage']['id']] = $val['Hage']['name'];
  }
  return $data;
 }
}
?>

コントローラーで宣言します。
/app/controllers/hoge_controller.php
var $helpers = array('Html', 'Form', 'Hoge');

ビューの任意の場所に書きます。
/app/views/hoges/index.ctp
e($hoge->hoge()); // wwwww
e($form->input('hage', array('type'=>'select', 'options'=>$hoge->hage(), 'label'=>false))); // セレクトボックス

■ありがちな文
updated = date("Y-m-d H:i:s");

$hogeData = $this->Hoge->read(null,$id);

$params = array(
'conditions' => array(
'status' => 0,
'or' => array(
array(
'Hoge.start_datetime >='=>$this->data['Hage']['start_time'],
'Hoge.start_datetime <='=>$this->data['Hage']['end_time'],
),
array(
'Hoge.end_datetime >='=>$this->dataData['Hage']['start_time'],
'Hoge.end_datetime <='=>$this->data['Hage']['end_time'],
),
)
),
'fields' => array('id', 'name'),
'order'=>array('Hoge.created' => 'DESC'),
'recursive' => -1,
);
$hogeDatas = $this->Hoge->find('all', $params);

foreach($hogeDatas as $rec){
if(){continue;} // 順番飛ばし
}

foreach ($hash as $key => $val) {
if(){break;} // 終了
}

■ラベルをいい感じに
#Form label {display:block; float:left; width:160px;}
form div {clear:left;}

■セッションに検索条件を保存
$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);
}
?>

■ページネイトした後のパラム
こんなのが付いてきますのでオリジナルのページャーを作ることも可能です。
$this->Paginator->params
    [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 にしたらよいのか、どうしよう。(-_-)

■クレジット決済機能のサーバー移転時の注意
本番のみサーバーのIP制限をかけている場合がたまにあります。
契約書以外の説明に載っておらず自分が知り得ないということと、テストアカウントでいろいろOKだったので分からんかった。
それが大手の場合はフットワークが無く、そうとう日数に余裕を持たせる必要があると考えるべき。

■ドメイン切替
ネームサーバーはそのままでDNSの設定を変更した場合(A,MX)、TTLの値を考慮。
どちらも変更できないので、とくにxserverは注意。
Xserver : 24時間
ムームーDNS : 1時間
お名前.com : 1時間

■全角空白で壺った
メール本文の全角スペースとかを消したかったんだけど、以下。
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あたりも漏れなく書き直すと無難。