PHPの最近のブログ記事

たとえば SmartyRenderer の場合、

  1. app/templates にベースとなるテンプレートファイルを作成(base.tpl)。コンテンツが入る場所には、{$inner} と書いておく。
  2. output_types.xml にレイアウトを作成
<layout name="default">
  <layers>
    <layer name="content" />
    <layer name="base">
      <parameters>
        <parameter name="template">%core.template_dir%/base</parameter>
      </parameters>
    </layer>
  </layers>
</layout>
  1. Smarty.class.php のあるディレクトリを include_path に追加。
  2. output_types.xml に renderer を追加。
<renderers default="php">
  <renderer name="php" class="AgaviPhpRenderer">
    <parameters>
      <parameter name="assigns">
        <parameters>
          (略)
        </parameters>
      </parameter>
    </parameters>
  </renderer>
</renderers>



<renderers default="smarty">
  <renderer name="smarty" class="AgaviSmartyRenderer">
    <parameters>
      <parameter name="assigns">
        <parameters>
          (略)
        </parameters>
      </parameter>
    </parameters>
  </renderer>
  <renderer name="php" class="AgaviPhpRenderer">
    <parameters>
      <parameter name="assigns">
        <parameters>
          (略)
        </parameters>
      </parameter>
    </parameters>
  </renderer>
</renderers>
  • テンプレートファイルの拡張子は、.tpl
  • View で assign した値 hoge には、{$template.hoge} でアクセスする
  • output_types.xml の中で assign した値に hoge には {$hoge} でアクセスする
  1. mod_rewrite を使えるようにしておく
  2. pub/dist.htaccess を .htaccess にリネーム
  3. .htaccess 内を以下の箇所を変更
RewriteRule On
RewriteBase / (ここは必要に応じて変更)

バージョンアップしてもなかなか解消されない、VS.php が文字列リテラルを勝手にインデントする件、特にPHPコード内にSQLを書く際に不便だったのですが、ヒアドキュメントの中は勝手にインデントされないことが分かったのでとりあえずそれで対応しています。

# 前のエントリを見ると、ヒアドキュメントも勝手にインデントされることになってますが、そんなことなかったですね...。

$string = <<<DOC
SELECT * ~
DOC;

少し面倒くさいけど、まあSQL文の行頭が揃ってしまうことに比べれば大分ましか。

というわけで、久しぶりに VS.php のサイトを見たら、バージョン2.4のβ版が出てますね。個人的に注目なのは、この辺でしょうか。

  • Xdebug搭載
  • Website Copy - ファイル転送機能の追加
  • HTML、PHPDocのインテリセンス機能の強化

アップデートが割とマメにされていてうれしい限りです。結構売れているのですかね。

まーだからどうしたって話ですけれども。キーもできればバリデーションしたいところだけど、時間の都合により却下。相変わらず再帰処理は自分の想像力の限界を超えかけてるんだぜ...。

Agavi もそうだけど、意外と PHPフレームワークの Validator は多次元配列に対応していない。Symfony とかはどうなんすかね。そういえば OpenPNE の次期バージョンは Symfony になるそうな。

と、いうわけでとりあえず必要な箇所を再帰的に。

  function _validateRecursiveArray (&$rule, &$result, &$key, &$values, &$empty)
  {    
    foreach ($values as $k => $value) {
      if (is_array($value)) {
        $this->_validateRecursiveArray($rule, $result[$k], $key, $value, $empty);
      }
      else {
        $value = $this->_filter($value, $rule['pre_filter']);
        if (is_null($value) || $value === '') {
          continue;
        }
        
        $this->_validate($key, $value, $rule);
        $result[$k] = $value;
        $empty = false;
      }
    }
  }

そして validate 関数を修正。

  /**
   * validate
   * 
   * @access public
   * @return boolean エラーが発生しなかったかどうか
   */
  function validate()
  {
    foreach ($this->rules as $key => $rule) {
      $rule = $this->_initRule($key, $rule);
      
      $values = array();
           
      if (isset($this->requests[$key])) {
        if (!is_array($this->requests[$key])) {
          $values = array($this->requests[$key]);
        }
        else {
          $values = $this->requests[$key];
        }
      }
      
      if (empty($rule['is_array'])) {
        $reqval = array_shift($values);
        $result = $this->_filter($reqval, $rule['pre_filter']);
        
        // 必須項目チェック
        if (is_null($result) || $result === '') {
          if (!empty($rule['required'])) {
            if (isset($rule['required_error'])) {
              $error = $rule['required_error'];
            }
            else {
              $error = "{$rule['caption']}を入力してください";
            }
            $this->_setError($key, $error);
          }
          else {
            if (isset($rule['default'])) {
              $result = $rule['default'];
            } else {
              $result = null;
            }
          }
        }
        else {
          $this->_validate($key, $result, $rule);
        }
      }
      
      else {
        $result = array();
        $empty = true;
        $this->_validateRecursiveArray($rule, $result, $key, $values, $empty);
        
        if ($empty) {
          if (!empty($rule['required'])) {
            if (isset($rule['required_error'])) {
              $error = $rule['required_error'];
            }
            else {
              $error = "{$rule['caption']}を入力してください";
            }
            $this->_setError($key, $error);
          }
          else {
            if (isset($rule['default'])) {
              $result = array($rule['default']);
            }
            else {
              $result = array();
            }
          }
        }
      }
      
      $this->_setParam($key, $result);
    }
    
    return empty($this->errors);
  }

ことの発端は、とある方から、例の旅行の写真をPCの壁紙にするので送ってくれと大変ありがたい依頼をいただいたこと。まあ自分としても携帯用の待受画像とか簡単に作れたらいいかもねってことで、ちょいとプログラムを書いてみました。

画像のリサイズは、仕事では歴史的経緯から execute で ImageMagick の convert を使っているのですが、いつも同じというのも芸がないので今回は GD 利用の image 関数群でやってみました。多分 GD の方がレンタルサーバー環境でも入ってる可能性が高いしね。

特に問題もなくあっという間に完成。これはなかなか便利かも。携帯の待ち受け画面にするときには、画像そのものじゃなくてQRコードを出力するようにすれば尚便利。

のむらの旅行写真集

<form>(と type="hidden" な <input>)タグを出力してくれる smarty プラグインがなぜかテンプレート関数プラグインなため、終了タグ(</form>)を出力してくれずテンプレートのタグの整合性が崩れるワナ。

この場面はどう考えてもブロック関数プラグインが鉄板。

個人的に請け負った案件で、オープンソースSNS OpenPNE をカスタマイズ中です。

イケそうかどうかを判断できる程度にしか下調べをせずにGoしてしまったのが運のツキ、一つのディレクトリに山のようにファイルが入っているため、開くファイルを探すという非常にどうでもよい時間が長く効率の悪いことこの上なし。

しかも、データベース関連の関数がテーブル単位でファイルにまとめられているため、中心的なテーブルを操作する関数が詰まったファイルが巨大になりがちでこれもまた本質的でない部分で非常に非効率的なのである。

そしてコメントもあまり入っていない......。

国産のオープンソースSNSは今のところこれがデファクトスタンダードっぽいのだけど、正直どうよと。こちらはカスタマイズした成果物をフィードバックしない完全なフリーライダーなのでもちろん文句を言える立場では全然ないし、オープン化に耐えないものであれば勝手に淘汰されていくだけなのでそういう意味でも文句を言うべき事象ではないのは明らかなのだけど、このやり場のないやるせなさといったらもう。

文句垂れついでに書いておくと、HTMLがインデントされていないのがどうしてもガマンできない。世の中には案外インデントしない派の人がいるのは経験的に分かっているのだけど、そういう人に限って堂々と整合性が崩れていたりしがちなワナ(OpenPNEではさすがにそれはないようですが)。

VS.Php 2.3

| | コメント(0) | トラックバック(0)

自分的にはすっかり定着したPHPの統合開発環境 VS.Php がバージョンアップ (だいぶ前ですが)。

公式サイト上によるとバージョンアップの目玉は、

    • Windows VISTA に対応!
    • リモート接続でファイル編集

とのことなのですが、個人的には上記2つはどうでもよくて、むしろ公式サイトでは「その他の追加情報」にすら含まれていない以下2つのポイント、

    • UTF-8以外のソースコードも普通に扱えるようになりました(プロジェクトごとにデフォルトの文字コードを指定できるようになりました)。
    • 新規HTMLファイルを作成したときに、一緒にPHPファイルが作られるというおせっかい仕様がなくなりました。

数少ない不満点のうち2つが解消されるという神バージョンアップなのでした。

あとはこのあたりが改善されるとパーフェクツか。

    • 複数行の文字列リテラル(SQL文とか、ヒアドキュメントとか)は勝手にインデントしないで欲しい
    • VS.Php 外で追加されたファイルをプロジェクトに追加するのがちょっとだけ面倒(ファイルビューのリロード→プロジェクトへのインクルードと二手間かかる)
    • PHPDoc形式のコメントを自動フォーマットしてくれない

どうせ読むので引き続き和訳

Configuration
-------------
All configuration files use the XML format now. All configuration files are validated against XML schemas, which means incorrect configuration files often result in an error right away. Also, XInclude (with XPointer) is supported, as well as "parent" configuration files that allow to enforce common settings for all projects in your organization. Of course, you can use any encoding you like for the XML files, but the default is UTF-8.

設定
-------------
全ての設定ファイルは XML フォーマットを使用します。全ての設定ファイルは XML スキーマによってバリデートされます。これは、正しくない設定ファイルはしばしば直ちにエラーとなることを意味します。親("parent")設定ファイルによって全てのプロジェクトに共通の設定を実行することが可能であり、また、XInclude (XPointer) もサポートされます。もちろん、XML ファイルにはどんな文字エンコーディングでも使用することができます(デフォルトは UTF-8 です)。

All configuration settings can either be valid under all situations, or only in one or more specific environments and/or contexts. This allows for very fine-grained control over what's happening. For instance, you can enable debug mode for the 'production' environment, or enable certain filters only in the 'web' context.

全ての設定は、全ての状況下で有効にすることも、一つあるいはそれ以上の特定の環境またはコンテキストで有効にすることもできます。これによりとてもきめ細かい制御が可能になります。たとえば、'production'環境においてデバッグモードを有効にしたり、あるフィルターを'web'コンテキストのみで有効にすることができます。

'contexts.ini' is gone, and we re-introduced 'factories.xml'. New config files are 'output_types.xml', 'routing.xml' and 'translation.xml'. 'filters.xml' was split up into separate files for global- and action filters.

'context.ini'はなくなり、'factries.xml'を再び導入しました。新たな設定ファイルは、'output_types.xml'、'routing.xml'、そして'translation.xml'です。'filters.xml'は'global-filters.xml'と'action-filters.xml'に分割されました。

'autoload.xml' 'compile.xml' and 'config_handlers.xml' use the "global" Agavi configuration files as their parents so it's not necessary anymore to sync them after each upgrade of Agavi.

'autoload.xml'、'compile.xml'、そして'config_handlers.xml'は、"global" Agavi 設定ファイル(訳注:agaviインストールディレクトリ/config/defaults/ 以下の同名ファイル)を親として使用するため、Agavi がアップグレードするたびにこれらを同期させる必要はなくなりました。

Only 'output_types.xml', 'factories.xml' and 'settings.xml' are now required for the system to run.

'output_types.xml'、'factories.xml'、そして'settings.xml'のみがシステムの実行に必須です。

このアーカイブについて

このページには、過去に書かれたブログ記事のうちPHPカテゴリに属しているものが含まれています。

前のカテゴリはLinuxです。

次のカテゴリはPRIDEです。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。