Logical Rabbit.

さくらのVPS

PHP

dockerでphpを起動していたら `strtotime(): It is not safe to rely on the system's timezone settings.~` と怒られたときの対処

なんか毎回「あーはいはいOSのTZ環境変数設定してなかったねー」で済ましては改善せずに英文読み直すことになるのでメモ(最初から英文読め)。

以下を記述した php.ini をdockerイメージ内に配置。Dockerイメージ内既存のphp.iniを上書きしていないかどうかは事前に確認すること。

php.ini:

[Date]
date.timezone = Asia/Tokyo

Dockerfile:

COPY ./php.ini /usr/local/etc/php/

どっとはらい。

AWS SDK for PHPでAmazon S3へアクセスするコードのメモ。

ぶっちゃけ技術検証で途中まで書いたのだけど、当面使いそうに無いのでココという蔵に「お蔵入り」です。

必要なもの

サンプルコード

  • AWS SDK for PHPはComposer等を使用せずに直接展開、 lib/ 以下に配置しています。Composer使った方が楽ですが、シェルログインできない環境の場合は手作業で配置した方が状況把握できてよいので。
  • バケット名は aws-test.logicalrabbit.jp 。予め作成しておきませぅ。

認証

  <?php
    require 'lib/aws-autoloader.php';

    use Aws\S3\S3Client;

    $s3client = new S3Client( [
      'region' => 'ap-northeast-1',
      'version' => '2006-03-01',
      'signature_version' => 'v4',
      'credentials' => [
        'key' => [アクセスキー],
        'secret' => [秘密鍵],
      ],
    ] );
  ?>

オブジェクト一覧の取得

テーブル化して一覧にしています。

    <table>
      <tr>
        <th>Key</th><th>Size</th><th>Last modified</th>
      </tr>
  <?php
    $result = $s3client->listObjects( [
      'Bucket' => 'aws-test.logicalrabbit.jp',
    ] );

    foreach( $result['Contents'] as $content ) {
      echo '<tr><td>' . $content['Key'] . '</td><td>' , $content['Size'] . '</td><td>' . $content['LastModified'] . '</td></tr>';
    }
  ?>
    </table>

オブジェクトの追加

取り敢えず lib/ 内に展開前のaws.zipがあったので、それをアップロードしてみるなど。アップロード成功の有無確認として、ETagを画面に表示します。

  <?php
    $reader = fopen('lib/aws.zip', 'r');

    $result = $s3client->putObject( [
      'Bucket' => 'aws-test.logicalrabbit.jp',
      'Key' => 'aws.zip',
      'Body' => $reader,
    ] );
    fclose( $reader );

    echo '<p>Uploaded a file. ETag = ' . $result['ETag'] . '</p>';
  ?>

この後で再度オブジェクト一覧の取得を実行すれば、オブジェクトが増えているのが確認できる筈。

「さくらのレンタルサーバー」でPHPバージョンを変更してもpeclが使用するPHPバージョンが上がらなかった話(解決)

PHP_PEAR_PHP_BIN=/usr/local/bin/php を設定すればOK。←結論

どっとはらい。

…いや備忘録として残しておきたかったので。なお、PHP本体のバージョンはさくらインターネットの「コントロールパネル」にて変更可能です。

% php -v
PHP 7.1.4 (cli) (built: Apr 17 2017 11:51:56) ( NTS )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.1.0, Copyright (c) 1998-2017 Zend Technologies
    with Zend OPcache v7.1.4, Copyright (c) 1999-2017, by Zend Technologies

PHPはv7.1になっています。

% pecl version
PEAR Version: 1.10.1
PHP Version: 5.6.30
Zend Engine Version: 2.6.0
Running on: FreeBSD www251.sakura.ne.jp 9.1-RELEASE-p22 FreeBSD 9.1-RELEASE-p22 #0: Wed Dec  3 15:24:48 JST 2014     root@www3304.sakura.ne.jp:/usr/obj/usr/src/sys/SAKURA17 amd64

しかし、peclは相変わらずPHP v5.6のまま。おかげでphp 7.xを要求するパッケージがインストールできなかったりします。

まずはphpコマンドの場所を確認。

% which php
/usr/local/bin/php

実際には /usr/local/bin/php-wrapper へのシンボリックリンクのようではありますが。

ログイン時、phpコマンドの場所を環境変数PHP_PEAR_PHP_BINにセットするようにします。その後取り敢えず現ログイン環境に反映。

% echo "setenv PHP_PEAR_PHP_BIN /usr/local/bin/php" >> .cshrc
% source .cshrc

再度peclが使用するPHPのバージョンを確認。

% pecl version
PEAR Version: 1.10.1
PHP Version: 7.1.4
Zend Engine Version: 3.1.0
Running on: FreeBSD www251.sakura.ne.jp 9.1-RELEASE-p22 FreeBSD 9.1-RELEASE-p22 #0: Wed Dec  3 15:24:48 JST 2014     root@www3304.sakura.ne.jp:/usr/obj/usr/src/sys/SAKURA17 amd64

これにて解決。

…したんだけど、肝心のmailparseがコンパイルエラーになって… ぐぬぬ。

PHP関連のメモ。

仕事でのメイン開発言語がPHPになったので。今までPHPをメインに使うことは無かったので(敢えて選択する理由が無かった)。お約束的な部分が色々分からんので自分用にメモ。

MySQL(MariaDB)に接続できないとき

  1. Socketが見つかっていない可能性を疑う
  2. php --ri mysqli とか php --ri pdo_mysql でパラメータをチェック
  3. Socketが設定されていない、もしくは正しくない場合は php.ini を確認
  4. そもそも何処の php.ini を見ているのか、と言う点を疑う
  5. 何処の php.ini を見ているかは、 php -i | grep php.ini とでもすれば分かる
    • 自分しか使わないマシンだったらとりま /etc/php.ini を設定していけば良いのだけど、ソースコンパイルしたPHP (php.7.1.1)だとそもそも <インストールディレクトリ>/lib/php.ini を見ていましたとさ。どっとはらい。
    • sudo ln -s /etc/php.ini <インストールディレクトリ>/lib/php.ini としたところ、/etc/php.ini を見るようになりました

FPDFで日本語を含むPDFファイルを作成する

PDFを扱うライブラリはいくつかあるのですが、PHP言語単体で外部ライブラリを必要としないものとしてはFPDFが有名らしく、日本語対応もされているので使い方を試してみました。なお、今回は「既存のPDFを加工する」のではなく「データからPDFファイルを新規に作成する」のが目的です。

基本的には座標を指定してごりごり書いていくようです。生のテキストをPDFに落とすというよりは、固定レイアウトの帳票とかを作成する用途に向いていそう。実際には方眼紙でレイアウト組んで、座標系で管理していく戦闘スタイルになると思われ。

各種画像も読み込んで貼り付けられるので、画像ファイルをまとめたPDFを作る用途にも使えそうです。

PHPによるメール処理(POP3編)

PHPでメールを送受信する処理について調べ始めたので、サンプルコードをGistに投稿しました。まずはPOP3から。

大雑把に以下の処理をしています。基本的に動作検証のためなので、エラーチェックはしないし取ってきたメールへの処理も雑極まりない感じですが。

実行にあたっては ./server_setting.ini を適当に用意してください。パスワードとか書く必要があるので、扱いは慎重に。また、メールサーバーにアクセスするため万が一の場合メールを破壊する可能性もあるかと思います。そのあたりは自己責任でお願いします。

…最大の難点は「取り敢えず最新メールを取ってくる」仕様なので、その時何が届いているか賭けになるということだな…。試験実行したらSPAMを拾ってきたこともあったし(汗)

  1. POP3サーバーにログインする
  2. メールの一覧を取得する
  3. メールの一覧から最後の1件(=最新のメール)を取り出す
  4. 取り出したメールのbodyをMIMEデコードする
  5. (この辺りから雑な実装になる)メールがtext/plainの、ふつーのメールだった場合デコード結果が単品になるので、そのままprint
  6. メールのパートごとにContent-Typeをチェックし、text/plainだったらそのままprint
  7. Content-Typeがtext/plainでないなら、連番を振ってファイル保存(面倒くさいのでファイル名の取得は省略している)

メールのリストを取得したあたりからプログラムの目的によってやることが変わってくると思うので、適宜調整すればいいと思われ。

PHPでライブラリパスを一時追加したい

PHPではrequire_once()は絶対パスを使ったほうがいいらしい。が、取り込んだライブラリ内で別のライブラリをrequireしてる場合、やっぱりinclude_pathをいじっておかないとダメよね、という時のお話。

素直にやるならphp.iniを書くのだけど、これだとインストールされてるPHPの標準的なinclude_path + 自分専用のinclude_pathにできない気がする。追加したいんですがあたしゃ。

<? php
$myLibPath = dirname( __FILE__ ).'/lib/';
ini_set( 'include_path', $myLibPath.':'.ini_get( 'include_path' ) );

# これ以降にrequire()とかを書く
?>

とやっていたら最終的に取り込んだライブラリが「PEAR.phpがないぞゴルァ」と言い出してどっとはらい。だったら最初からpear使えばいいんじゃ… orz

参考サイト; [PHP]require(require_once)するときは必ず絶対パスを使いましょう