5丁目通信(仮称)

とある5丁目で活動する還暦を過ぎたWebプログラマーの覚え書きです。それとかかってくる迷惑電話や、家業のアパート経営について。

タグ: PHP

  • 昨日のCakePHPでhasManyでの検索の続きの話し

    昨日のCakePHPでhasManyでの検索の続きです。うまくいったと思いましたが、検索結果に重複項目があります。hasManyのモデルにまともにSQLを実行したら重複するのは当たり前ですね。

    そこで、pagenate()でページングの処理をしているので、コントローラーのメンバー$pagenateのfieldsに、キーとなる項目にDISTINCTを付けてみる。これで、重複されなくなった。

    しかし、新たな問題。検索個数が合わない。こちらもcount(*)になっているところをcount(DISTINCT キー項目)にすればいいのだけど、$pagenateのfieldsからは影響されないようでした。

    いろいろ調べてみると、やはりありました。ここです。モデルにpaginateCount()を定義してあげればいいのでした。pagenate()のソースを見ると、モデルにpaginateCount()があるかどうかをチェックして、あればpaginateCount()を実行してくれます。無ければfindCount()を実行します。ここはSQLをゴリゴリ書いて、該当する条件でレコード数を返してあげるようにしました。配列に格納されている条件は次のようにWHERE句に変換できます。

    $Db = ConnectionManager::getDataSource($this->useDbConfig);
    $where = $Db->conditions($conditions);

    これで、重複せずに検索結果を表示できました。

    いまいち具体的な説明ではないので、もしご興味ある方はコメントに入れてください。

    著:山田祥寛
    ¥3,366 (2025/04/25 12:34時点 | Amazon調べ)
    著:松浦 健一郎, 著:司 ゆき
    ¥2,574 (2025/04/25 12:34時点 | Amazon調べ)
    著:谷藤賢一, 著:徳丸浩
    ¥2,750 (2025/04/25 12:34時点 | Amazon調べ)
  • CakePHPでhasManyのモデルに対して条件式を書いた話し

    CakePHPロゴ

    ただ今、CakePHPでWebサイトを開発しています。今回は、検索条件を設定して抽出して結果をリストにするという、定型的な検索サイトです。

    あるモデルに対して検索条件を与えるのは普通です。CakePHPの場合、belongsToのような外部参照の関係であるモデルにも検索条件を与えても、簡単に抽出してくれます。

    しかし、hasManyの関係にあるモデルの項目に検索条件を書いてあげるとSQLを発行しているところでエラーになります。SQLのデバックログによると、hasManyのモデルに対しては、SQLでleft joinを作ってくれません。これで、未定義のテーブルということでSQLエラーになります。

    Googleで検索してみると、このように書けばOKと書いている。しかし、これではhasMany以外の関係のモデルを検索してから、hasManyのモデルにフィルターをかけているだけなので、検索結果が違ってくる。

    無理矢理SQLを生成してみることもやりましたが、ビューに渡す結果を生成するのが大変なので止めました。

    いろいろと調べてみると、ここにありました。後からhasManyのモデルに対してjoinを設定すればいいのです。モデルに対して、beforeFind()を定義してあげることが必要でした。CakePHPのソースを追ってみると、findAllのところでオプションにjoinが使えるように定義されていました。これで無事にhasManyのモデルでも条件式を書くことができました。

    すべてのサイトに感謝です。

    著:山田祥寛
    ¥3,366 (2025/04/25 12:34時点 | Amazon調べ)
    著:松浦 健一郎, 著:司 ゆき
    ¥2,574 (2025/04/25 12:34時点 | Amazon調べ)
    著:谷藤賢一, 著:徳丸浩
    ¥2,750 (2025/04/25 12:34時点 | Amazon調べ)
  • CakePHPでNot foundエラーが出た話し

     

    CakePHPで開発しているときに、以下のメッセージが表示されてしまった。

    Not found
    
    The requested address was not found on this server.

    調べてみると、いろいろ原因があるようだが、自分の場合は、Modelが正しく設定されていないのが原因であった。core.phpのDebug.level を1にすれば、原因はすぐにわかる。そういえば、携帯電話対応のために、メッセージがうるさいので0にしていた。

    以上、覚え書き。

    追記

    一つのテーブルのアクセス権が設定されていないのが原因だった。ただし、まだまだエラーだらけ・・・。

    著:山田祥寛
    ¥3,366 (2025/04/25 12:34時点 | Amazon調べ)
    著:松浦 健一郎, 著:司 ゆき
    ¥2,574 (2025/04/25 12:34時点 | Amazon調べ)
    著:谷藤賢一, 著:徳丸浩
    ¥2,750 (2025/04/25 12:34時点 | Amazon調べ)
  • 必要のない仮想シリアルポートの削除するためのユーティリティーの話し

    シリアルコード

    WindowsのPCにUSB-シリアル(RS-232C)ポート変換ケーブルをつないだとき、自動的にポート番号を付けてくれる。しかし、COM12とか大きな番号に付けられたとき、アプリケーションのほうで対応していない場合がある。

    ポート番号を付け替えることもできるが、使っていないのにCOM1からCOM10まで使用中になっているときがある。これは以前接続してた機器の情報が残っているのが原因。例えばauのLISMO Portの場合、何回も再インストールするとどんどん別のポート番号を使っていってしまう。

    Vistaのデバイスマネージャーからいらないシリアル機器のドライバーを削除しようとしても、接続していないとリストに出てこないので削除できない。

    諦めかけたときに見つけたユーティリティー。接続していないものも含めて仮想シリアルポートの一覧を表示してくれる。この一覧からデバイスドライバーを削除できる。ユーティリティーで、COM1からCOM10までいらない仮想シリアルポートを整理できた。作者に感謝! → 追記参照

    無線機とPCを連動するソフトウェアはシリアルポートを必ず使う。しかも、COM1からCOM10までしか使えない。シリアルポートがないPCが増えてきましたので、どうしてもUSBシリアル変換ケーブルが必要になります。シリアルポートを増設する拡張ボードは高いので買えないし、ノートPCには入れることができない。したがって、仮想シリアルポートで接続する必要がありますので、こんな作業が必要になります。

    追記

    仮想シリアルポートの一覧を表示して削除するユーティリティのリンク先がなくなっていたので、代わりに「仮想シリアルポート 削除」で検索すると、Windows上で削除できるみたい。私は試していないけど、お試しを。

  • PukiWikiでユーザー認証できなくなっていた話し

    今サポートをやっているゴルフゲームですが、そのサポートページはPukiWikiで作っています。久しぶりにページを更新しようとしたら、編集のユーザー認証ができなくなっている。

    パスワードを間違えていると思って再設定しても変わらない。そういえばと気がついた。

    今使っているサーバーがPHP5にバージョンアップされたと同時に、mod_phpからCGI版のPHPに変更なっていた。昔に連絡をもらっていたが、なかなかバージョンアップされてなかったので忘れていた。いつの間にかバージョンアップされていた。

    CGI版のPHPになるとPEAR:Authが使えなくなって、PEAR:Authを使っているPukiWikiはユーザー認証できなくなるという訳。CGI版PHPに変わったところで影響のないと思っていたが、こんなところでひっかかるとは。

    そこで、CGI版PHPへのPukiWikiの対応方法はここに書かれているが、時間を見て対応しておこうと思う。その間は更新するときは設定ファイルを書き換える。原始的な方法。だって、ユーザーは私一人だし、あまり更新しないし・・・。

    でも何でCGI版PHPにするかな? 何かレンタルサーバー会社にとって意図があるのかな???

    著:山田祥寛
    ¥3,366 (2025/04/25 12:34時点 | Amazon調べ)
    著:松浦 健一郎, 著:司 ゆき
    ¥2,574 (2025/04/25 12:34時点 | Amazon調べ)
    著:谷藤賢一, 著:徳丸浩
    ¥2,750 (2025/04/25 12:34時点 | Amazon調べ)
  • WordPressのショートコードの実験

    WordPressには、簡単に独自機能を記事に埋め込めるショートコードとあるらしいので実験してみる。

    例えば、ここのサイトを参考にして

    [hw]

    と記述すると(両側の括弧は1バイトです)、

    [hw]

    と表示される。つづいてここのサイトを参考にして、

    [bk1_vc id="03092262" title="WordPress 2.7対応「導入&カスタマイズ」実践ガイド"]

    と記述すると、

    [bk1_vc id=”03092262″ title=”WordPress 2.7対応「導入&カスタマイズ」実践ガイド”]

    とbk1のバリューコマースのアフリエイトのリンクが表示されるように、ショートコードを書いてみた。これでわざわざ、MyLinkの変換ページでURLとか画像とかをコピーしなくてよくなった。ただし、適当なIDの決め打ちですので間違えているかも。とりあえず動いているレベルです。

    bk1のAPIの仕様がわかれば、もっとパラメータのチェックをきちんとすればいいかもしれません。Amazonみたいに、商品IDからいろいろな情報を取得できるようなAPIをbk1は用意していませんでしたよね?

    30分で作成した簡単なものですが公開します。divタグのclassを打っていますので、適当にCSSでデザインしてください。あとIDを変えてあげないと、全部アフリエイトは私がいただきます。

  • XOOPSサイトのサーバーを移行した話し

    お客様の希望で、サーバーを私の会社が面倒見ているサーバーに移行しました。ディスク容量は2倍になって料金はそのまま。しかし、そんなにディスクを使っていないのでサーバー会社のメリットはないかも。しかし、私の会社で面倒見てあげられるというのがメリットかも。

    お客様のサイトはXOOPSで作成したサイトです。最初は、素直にXOOPSをインストールしてコンテンツを移行していこうと思いましたが、時間と手間を惜しんで一挙にデータベースとプログラムファイルをコピーしてしまいました。大抵はここではまります・・・。

    データベースをエクスポート/インポートしたら、文字コードがEUCからUTF-8になってしまいました。移行先のMySQLで新規にデータベースを作るとUTF8にしてしまうらしい。無理矢理EUCでインポートしてもいいのだけど、あとあとトラブルになるのがいやなのでそのままUTF-8することにします。

    しかし、サイトは見事に文字化けです。モジュールに読み込むLanguageファイルをすべてUTF-8に変換してしまいます。シェルで変換スクリプトを作っておけばいいのですが、そんなに手間ではないだろうと秀丸エディタをつかって地道にUTF-8に保存していきます。xoops_trust_pathのディレクトリも忘れずに。

    /language/japanese/global.php の

    define('_CHARSET', 'EUC-JP');

    define('_CHARSET', 'UTF-8’);

    にします。これは、METAタグのcharsetの指定しているところです。

    最後にメールのタイトルの文字化けを修正します。文字化けの修正方法は、ここに載っています。

    以上で、無事に移行完了です。

    著:山田祥寛
    ¥3,366 (2025/04/25 12:34時点 | Amazon調べ)
    著:松浦 健一郎, 著:司 ゆき
    ¥2,574 (2025/04/25 12:34時点 | Amazon調べ)
    著:谷藤賢一, 著:徳丸浩
    ¥2,750 (2025/04/25 12:34時点 | Amazon調べ)
  • メールアドレスにハイフンが含まれているとWAKWAKのCGIではメールを送信できないなのね、という話し

    デザイナーからヘルプがありまして、プロバイダのWAKWAKが用意しているCGIで、sendmailの送信できないとものでした。

    WAKWAKのサーバー上では、PHPは動かなくて、perlを使ったCGIでメールの送信をしなければいけません。お客様から提供されたのはperlで作成されたメールフォールのプログラムを設定します。

    最近ご無沙汰のperlですが、プログラムの説明通り、パーミッションを設定したり、文字コードをシフトJIS(!)に変換してみたり、アスキーでアップロードしたりと設定してきました。入力項目のチェックも通っていますし、メールを送信のサンキューページも表示されます。しかし、メールが送信されてきません。

    Googleで調べてみると、何とWAKWAKて提供するメールサーバーは、宛先のメールアドレスのドメインに-(ハイフン)が含まれているとメールが送信されないという報告が見つかりました。

    試しに、ハイフンがドメインが含まれていないgmailのメールアドレスにしてみると、正常にメールが送信されました。

    そんなのあり? お客様には現象を説明して、どうするかを考えてもらいましょう。

    一番は、WAKWAKのサーバーでCGIを動かさないこと。別のサーバーを借りてもらうことです。

  • CakePHP URLの指定 - 例えば、htmlヘルパーのlinkのパラメータの話し

    CakePHPを使っていると、ヘルパーなどのリファレンスを解説本では簡単に説明を済ませているところに当たります。CakePHPのマニュアルをよく見れば書いているのですが(ただし、日本語サイトは遅れている場合があり)。

    例えばhtmlヘルパーのlinkの説明ところ。Webとか解説本には、

    HtmlHelper::link($title, $url = null, $htmlAttributes = array(), $confirmMessage = false, $escapeTitle = true)
    
    $title : タイトル
    $url : リンク先URL
    $htmlAttributes : 属性
    $confirmMessage : 確認メッセージの有無
    $escapeTitle : エスケープの有無

    などど書いていています。$urlは、”http://testtest.jp/”のようなURLをテキストで設定するようにサンプルに書かれています。

    しかし、CakePHPではURLの指定は、

    array('controller' => コントローラ名, 'action'=>アクション名)

    のように連想配列で指定可能なのです。もし、管理者サイトでは、

    array(Configure::read('Routing.admin') => true,'controller' => コントローラ名, 'action'=>アクション名)

    のようにすればいいのです。アクション名には’admin_’とかは付ける必要はありません。

    CakePHPを使いこなしている人なら当たり前かもしれませんが。一応、自分の覚え書きです。

    あとlinkのURLに関連して、ここのサイトに書かれていますが(感謝!)、IDなどの検索条件のパラメータをpaginatorヘルパーに含めるには、 Veiwで$paginator->optionsにurlをキーにした連想配列を設定すればいいようです。Veiwで$paginator->optionsのurlに設定してしまうと、View内のpaginatorヘルパーでsort()などのリンク先には、’val1/val2’が勝手に付けてくれます。

    もし、このようにパラメータが付けてアクセスしたときに、

    http://testtest.jp/コントローラー/アクション/val1/val2/

    ビューの最初で

    <?php
    $paginator->options = array(
      'url' => $this->passedArgs
      );
    ?>

    とすると、passedArgs変数は、パラメータを持っていますので、ビュー内の

    <?php echo $paginator->sort('title');?>

    は、

    http://testtest.jp/コントローラー/アクション/val1/val2/page:1/sort:title/direction:asc

    というようなパラメータを付けたリンクを作ってくれます。

    著:山田祥寛
    ¥3,366 (2025/04/25 12:34時点 | Amazon調べ)
    著:松浦 健一郎, 著:司 ゆき
    ¥2,574 (2025/04/25 12:34時点 | Amazon調べ)
    著:谷藤賢一, 著:徳丸浩
    ¥2,750 (2025/04/25 12:34時点 | Amazon調べ)
  • CakePHP 日付の月の選択フォーマットの指定。月を英文から数字で表示する話し

    CakePHP

    現在、CakePHPでニュースリリース管理を作成しています。そこで、リリースの日付を入力するところがあるのですが、CakePHPのそのままのHtmlヘルパーを使って日付を入力してしまうと、日本人向けではないフォーマットで選択させてしまう。

    例えば、

    $option_datetime = array(
      'type'         => 'datetime',
      'timeFormat'=> 24,
      'dateFormat'=> 'YMD',
      'legend'    => false,
      'label'        => false,
      'div'        => false,
      'interval'    => 15,
    );
    
    echo $form->input('release_date', $option_datetime);

    のようにする。

    これだと、月が英文(”Januaru” ~”December”)で選択させる。dateFormat属性の指定は、date()のfomartになるかと思えば違っていた。仕方ないので、formヘルパー(/cake/libs/view/helpers/form.php)に手を入れようとした。しかし、FormHelperクラスの__generateOptionsメソッドのこの部分

    case 'month':
      if ($options['monthNames']) {
        $data['01'] = __('January', true);
        $data['02'] = __('February', true);
        $data['03'] = __('March', true);
        $data['04'] = __('April', true);
        $data['05'] = __('May', true);
        $data['06'] = __('June', true);
        $data['07'] = __('July', true);
        $data['08'] = __('August', true);
        $data['09'] = __('September', true);
        $data['10'] = __('October', true);
        $data['11'] = __('November', true);
        $data['12'] = __('December', true);
      } else {
        for ($m = 1; $m <= 12; $m++) {
          $data[sprintf("%02s", $m)] = strftime("%m", mktime(1, 1, 1, $m, 1, 1999));
        }
      }
    break;

    を見ると、マニュアルにないmonthNames属性があることがわかる。上記の$option_datetimeに

    'monthNames' => false,

    を追加すれば、月が’01’~’12’になる。ソースは読んでみるものだ。

    しかし、このソースを書いた人は、date()を頭にないような感じがする。本当ならば、dateFormat属性がdate()のフォーマット指定のように振る舞えればいいのだが。

    著:山田祥寛
    ¥3,366 (2025/04/25 12:34時点 | Amazon調べ)
    著:松浦 健一郎, 著:司 ゆき
    ¥2,574 (2025/04/25 12:34時点 | Amazon調べ)
    著:谷藤賢一, 著:徳丸浩
    ¥2,750 (2025/04/25 12:34時点 | Amazon調べ)