5丁目通信(仮称)

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

タグ: プログラミング

  • #PHP のis_file()で必ずfalseが返ってしまう話し

    タイトル通り、PHP のis_file()で必ずfalseが返ってしまうということで、丸半日悩んだこと。原因は簡単なことでした。簡単なことだけど、どうせ忘れるので、覚え書きを書いておきます。

    ファイルが存在するのに、is_file()で必ずfalseが返ってしまいます。調べてみたら、フルパスでファイルを指定しろとか言われます。最初からフルパスの指定です。

    ローカルのVagrantで動かしているサーバー上では、正しくtrueが返ります。テストサーバーで使用している実サーバーではfalseになってしまいます。両方ともCentOSでバージョンも同じ。PHPもバージョンも同じです。

    $path_name = Configure::read('Pdf.upload_dir') . $fileName;
    if( is_file($path_name) ){
        :
        :
    

    このようなCakePHPのコードです。デバックすると正しくパスからファイル名が設定されています。

    ふと気なったのは、ファイル名の後ろに空白が入っていた。まさかと思ってtrim()で空白をカットしてみる。

    するとうまくいった。だけど、どうしてローカルで動いていたかは謎です。

  • PHPで西暦を和暦に変換する処理を書いた話し

    西暦を和暦に変換する処理を書きました。

    <? php echo "平成". (date("Y") - 1988) . "年", date("n月j日"); ?>
    
    平成26年3月27日

    本当だったら、西暦和暦変換関数なんてゴリゴリ書かなければいけないのですが、現在の日付を変換するだけで過去の年号に対応しなくてよい処理なので、これでよしとしました。よくあるサンプルだと、大正、明治、慶応とか変換してくれるものがありますが、あまり複雑にしても仕方ないのでシンプルにしました。シンプルが大事。コードを見て、ふざけんな、と言う人がいるかもしれません。だって、昭和の年(1988年以前)だったら、マイナスの年になりますから・・・。

    ただし、いずれにしても平成でなくなったら対応する必要があります。

    和暦は面倒なので西暦でやりたいのですが、お客さんのご希望なので仕方ありません。

    著:山田祥寛
    ¥3,366 (2025/03/27 13:40時点 | Amazon調べ)
    著:松浦 健一郎, 著:司 ゆき
    ¥2,574 (2025/03/27 13:40時点 | Amazon調べ)
    著:谷藤賢一, 著:徳丸浩
    ¥2,750 (2025/03/30 15:22時点 | Amazon調べ)
  • jQuery UIのタブ内からの別タブへのリンクで手こずったけど解決した話し

    jQuery UIのタブ内からの別タブへのリンクしてタブを切り替えることのメモ書き。ツレの案件で少し手間取ったので、その覚え書き。

    jQuery UIのタブが次のように書く。適当なJQueryとjQuery UIのCSSとJavaScriptを設定できていることが前提。この辺りは、jQueryUIのサイトに書いてある。

    <link href="css/import.css" rel="stylesheet" type="text/css" />
    <link href="css/jquery-ui.css" rel="stylesheet" />
    <script type="text/javascript" src="http://codeorigin.jquery.com/jquery-1.10.2.min.js"></script>
    <script type="text/javascript" src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>

    以上のように設定してある。

    JQueryUIのタブは、次のように設定する。

    <script type="text/javascript">
      $(function() {
      $( "#tabs" ).tabs();
      });
    });
    <ul>
      <li><a href="#tabs-1">タブ1/a></a></li>
      <li><a href="#tabs-2">タブ2</a></li>
      <li><a href="#tabs-3">タブ3</a></li>
    </ul>
    <div id="tabs-1">タブ1の内容</div>
    <div id="tabs-2">タブ2の内容</div>
    <div id="tabs-3">タブ3の内容</div>

    単純にタブ1の内容に、

    <a href="#tab1-1">タブ2を表示</a>

    と書いてもタブ1がタブ2に切り替えることができない。そこで次のように書く必要がある。

    <script>
      $(function() {
      $( "#tabs" ).tabs();
    
      $('a.tab_link').click(function() {
        $( "#tabs" ).tabs( "option", "active", $(this).attr('rel') );
        $( "#tabs" ).tabs( "refresh" );
        return false;
        });
      });
    </script>
    
    <ul>
      <li><a href="#tabs-1">タブ1/a></a></li>
      <li><a href="#tabs-2">タブ2</a></li>
      <li><a href="#tabs-3">タブ3</a></li>
    </ul>
    <div id="tabs-1">タブ1の内容。<a class="tab_link" href="#" rel="2">タブ2を表示</a></div>
    <div id="tabs-2">タブ2の内容</div>
    <div id="tabs-3">タブ3の内容</div>
    

    リンクのrel属性は、0~2がタブ1~3に対応している。

    jQueryUIのバージョンによって、動きが変わっているかもしれないので注意が必要。「jQuery UI タブ リンク」でGoogleで検索した結果で、参考になりそうなサイトのコードで試してみたけど動かなかった。結局はjQueryUIのサイトからAPIのマニュアルを見て、自分で作ったのでした。

    Tabs Widget | jQuery UI API Documentation

    jQuery UI
    技術評論社
    ¥1,980 (2025/03/25 15:17時点 | Amazon調べ)

  • TortoiseGitでエクスプローラーの右クリックが応答なしになったので対応した話し

    TortoiseGitをインストールしていて、エクスプローラーの右クリックが応答なしになってしまうときの対応メモを残しておきます。今のところ、応答なしにならないので、これでいいかはわかりません。自分のところでは、うまくいっている程度で読んでください。

    エクスプローラーの右クリックをしたときに、何も反応が無くて、最後に応答なしで終わってしまう現象が起こりました。右クリックを使っているアプリケーションをアンインストールした結果、原因はGitのWindowsクライアントのTortoiseGitでした。TortoiseGitは、プログラミングでよく使っているのでアンインストールはできません。

    いろいろと設定を変更をしたところ、次の設定で解消しました。

    • TortoiseGitのSettingsを起動します。エクスプローラーの右クリックからSettingsは起動できますが、応答なしになってしまいますので、スタートメニューから起動します。
    • 「アイコンオーバーレイ」の「アイコンオーバーレイ/状態表示列」を「エクスクローラー上でのみオーバーレイとコンテキストメニューを表示」にチェックします。
    • 同じく「状態のキャッシュ」で「拡張したシェル」を選択します。
    • 含めるパスに、Gitのリポジトリのあるフォルダをしてします。自分の場合は、「C:\Users\ando\workspace\*」となります。

    以上の説明は言語を日本語にしたときの設定です。英語の場合は、適当に読み替えてください。

    著:湊川あい, 著:DQNEO
    ¥2,208 (2025/04/01 17:15時点 | Amazon調べ)
    著:リック・ウマリ, 翻訳:吉川邦夫
    ¥3,247 (2025/04/01 17:15時点 | Amazon調べ)
  • Eclipseのファイルの切り替えを速くする。

    普段プログラミングで使っているEclipseで、ファイルの切り替えが遅くなっています。上のタブをクリックして別のファイルに切り替えるだけでも、2~3秒待たされます。ファイルをオープンするときも待たされます。

    たかが2~3秒でも反応がないと、イライラします。このままだと、このイライラが開発に支障がきたします。

    新しくEclipseをダウンロードしてインストールしても変わりません。プラグインを入れすぎという原因でもなさそうです。

    Googleさんに聞いてみると、メモリの設定でEclipseの起動が速くなるとのこと。早速試してみます。eclipse.iniに記述されているメモリの最小と最大の設定の部分を、以下のよう変えてみます。

    -Xms512m
    -Xmx1024m

    するとサクサクファイルを切り替えることができるようになりました。

    普段のPCはメモリをたくさん積んでいた方がいいですね。ちなみに今のPCは8GBです。まだまだです。

    追記

    しばらく経ったら、前と余り変わらない遅さになってしまった。

    おそらくEGitかJGirtが原因なのかと思います。アンイントールしたらファイルの切り替えが速くなりました。便利だったのに残念です。

    追記の追記

    速くなったと思ったら、変わらず2~3秒ファイルの切り替えに待たされます。EGitでもなさそうです。

  • ADIFのマルチバイト対応は難しいという話し

    アマチュア無線のログデータを交換するデータ形式にADIF(Amateur Data Interchange Format)というものがあります。趣味のプログラムでインポートクラスライブラリをPHPで作成してみました。

    ADIFでは

    Head Data Head Data Head Data
    <eoh>
    <call:6>WN4AZY<band:3>20M<mode:4>RTTY<qso_date:8>19960513<time_on:4>1305<eor>
    <call:5>VK9NS<band:3>40M<mode:5>PSK63<qso_date:8>20101022<time_on:4>0111<eor>

    のような形式になります。元々の仕様は、シングルバイトしか考えていないようなので、こちらに日本語を含んだマルチバイト文字を設定すると対応が難しくなります。見ての通り、コロン(:)の次にはデータ長が入ります。例えば、日本で一番使われている某ログソフトではシフトJISしか考えていないので、日本語を含んだコメントは

    <comment:6>テスト

    のようにマルチバイト文字は2バイトで出力されてしまいます。しかし、UTF8上では、2バイトに限らないので、このデータ長での指定は使えません。<>の区切り文字で解析していくことになります。コメントに<を使われたりすると、値の終了がどこだかわからなくなってしまいます。シフトJISのまま処理しようすれば、マルチバイト文字の2バイト目に<を使われれば難しくなります。

    ADIFのドキュメントを読んでも<>:のような区切り文字をエスケープすることは記述されていませんので、どうしてもデータ長で値を読み込んで行くのでしょう。

    某ログソフトのADIFのエクポートが、

    <comment:3>テスト

    のように、文字数で出力してくれればいいのにと思うのですが、昔のシフトJISを基準にしているので無理だろうなと思うのでした。後はADIFのバージョン3に記述されているXMLベースのADXファイルフォーマットに期待です。

    著:加納勉, 編集:Webon編集部
    ¥480 (2025/03/29 01:48時点 | Amazon調べ)
    CQ出版
    ¥1,650 (2025/03/29 01:48時点 | Amazon調べ)

    電波を出すには必ずアマチュア無線の国家資格が必要です。電波法令を守って楽しみましょう。

  • CakePHP2のテストで、$defaultのDBを見に行ってしまう件、解決した話し

    CakePHP2のテストで、$defaultのDBを見に行ってしまう。と書きましたが、解決しました。

    /App/Model/AppModel.php で__construct()を定義したとき、正しく引数を受け取って親クラスに渡してあげないといけなかったようです。

    public function __construct($id = false, $table = null, $ds = null) {
        parent:__construct($id, $table, $ds);
        // 何かの処理
       }

    のように引数を明示的に書いてあげます。

    テストケースのsetup()にあるモデルを設定しているClassRegistry::init()が中で$useDbConfigをtestでモデルオブジェクトをインスタンスにしているところがあって、そのときのパラメータがクラスに引き渡されていないのが原因でした。

    著:山田祥寛
    ¥3,366 (2025/03/27 13:40時点 | Amazon調べ)
    著:松浦 健一郎, 著:司 ゆき
    ¥2,574 (2025/03/27 13:40時点 | Amazon調べ)
    著:谷藤賢一, 著:徳丸浩
    ¥2,750 (2025/03/30 15:22時点 | Amazon調べ)
  • CakePHP2のテストで、$defaultのDBを見に行ってしまう話し

    CakePHP2でテストするときに、/app/Config/database.phpの$testではなくて$defaultで指定したDBを見に行ってしまいます。こちらの対処方法のメモ。

    テーブルにtext型の項目があると、memoryではなくてMyISAMでテストのテーブルを自動的に作りに行きます。この辺りが関係しているかもしれません。こちらはbakeすると、Fixtureの$fieldsの中にtableParametersに設定されています。

    テストの途中でexit()して上げると、$testのほうのDBにテストのためのテーブルをFixtureからcreate tableしてくれていることを確認できます。しかし、テストケースでは、$defaultのほうのDBを見に行きます。

    CakePHP2のCookbookに書いているように、Fixtureに

    public $useDbConfig = 'test';

    と書いてもダメでした。

    public $import = array('table' => 'articles', 'connection' => 'test');

    のようにしてもダメ。

    結局は、

    class ArticleTestCase extends CakeTestCase {
        public $fixtures = array('app.Article');
        public function setUp() {
            parent::setUp();
            $this->Article = ClassRegistry::init('Article');
            $this->Article->useDbConfig = 'test';
        }

    のように無理矢理モデルの$userDbConfigにtestをして対応しました。

    もっと良い方法があるのでしょうね。これだと、joinされたFixtureのテーブルデータだと見つからないのてテストできないとか問題が残ります。

    マニュアルに書いていないことは何とか対応しなければいけないのは大変です。

    著:山田祥寛
    ¥3,366 (2025/03/27 13:40時点 | Amazon調べ)
    著:松浦 健一郎, 著:司 ゆき
    ¥2,574 (2025/03/27 13:40時点 | Amazon調べ)
    著:谷藤賢一, 著:徳丸浩
    ¥2,750 (2025/03/30 15:22時点 | Amazon調べ)

    続きはこちらから

  • 無事にサービスイン。

    今まで他社で開発していたサイトを引き継いで、リニューアルしてサービスイン。

    今回はデータベースだけを残して、プログラム類はすべて書き直し。だって、PHPを使っていても、クラスって何かしら、SQLインジェクションなんて関係ないぜ、PHPってHTMLに埋め込むのよね・・・、と言った作り方。反対に大昔のPHPの解説本に載っているサンプルみたいで読みやすいこと。一気にCakePHPで書き換えた。

    切り替えは1時間で済んだ。これも予行演習をやったおかげ。マニュアルは大切。

    Google+: View post on Google+

  • CakePHPのビューを変数に格納する話し

    メールの本文をビューを使って生成したときがあります。PHPのストリングで結合してなんてやりたくありません。後で修正が面倒。

    CakePHPの1.3のときは、

    $this-&gt;output_layout = 'mail';
    
    // バッファリング開始
    ob_start();
    
    // Viewアクションでレンダリングする。
    $this-&gt;render('mail_view');
    
    // レンダリングした結果を取得する。
    $html = ob_get_clean();

    なんてob_start()とrender()でやっていたけど、CakePHPが2になってからrender()がレンダリング結果を返さなくなったようだ。

    そこで、viewのソースファイルを読んで、次のように対応した。

    // Viewアクションでレンダリングする。
    $response = $this-&gt;render('mail_view', 'email');
    
    // レンダリングした結果を取得する。
    $html = $response-&gt;__toString();

    なんだか__toString()とか内部のメソッドを呼んでいるが、もっとよい方法があるのだろうか?

    著:山田祥寛
    ¥3,366 (2025/03/27 13:40時点 | Amazon調べ)
    著:松浦 健一郎, 著:司 ゆき
    ¥2,574 (2025/03/27 13:40時点 | Amazon調べ)
    著:谷藤賢一, 著:徳丸浩
    ¥2,750 (2025/03/30 15:22時点 | Amazon調べ)