タグ: PHP

PHPアプリケーションをHerokuにデプロイするときに”ERROR: Couldn’t parse ‘composer.lock’; it must be a valid lock”エラー

PHPアプリケーションをHerokuにデプロイしようと思い、

git push heroku master

としたところ

-----> PHP app detected
-----> Bootstrapping...
-----> Installing platform packages...
 ! ERROR: Couldn't parse 'composer.lock'; it must be a valid lock
  file generated by Composer. Run 'composer update', add/commit
  the change, then push again.
 ! Push rejected, failed to compile PHP app.
 ! Push failed

となりデプロイが失敗。

composer.lockは存在しており、指示通りcomposer updateをしてcomposer.jsoncomposer.lockを更新したうえでデプロイしても同じエラーが発生しました。

php – Heroku ERROR: Failed parsing composer.lock; it must be non-empty and valid JSON – Stack Overflow

より

composer self-updateでcomposer自体を更新し、composer updateしたうえで、デプロイすることでエラーが出なくなりデプロイできました。

広告

phpMyAdminでDATETIME型が「BLOB」と表示される

  • PHP5.6
  • Apache 2.2
  • MySQL 5.6

をソースからビルドし

  • phpMyAdmin4.6.4

を設置・設定したうえで、DATETIME型を含むテーブルを作りデータを投入後、phpMyAdminから内容を確認すると、

DATETIME型がBlog表示

と表示されてしまいました。

MySQLコマンドでのSELECTやMySQL Workbenchを使って確認したところ、日付として表示されており問題がない状況。

調べたところ、

php – phpMyAdmin: Date Fields Display as BLOB – Stack Overflow

が見つかり、phpinfo()でPHPのMySQLモジュールに何が使われているのか確認したところ、mysqlモジュールが使われていました。
そこで、mysqliモジュールを使うようにビルドしなおしたところ、

DATETIME型が正常に表示

と正常に表示されるようになりました。

FuelPHPにRollbarを組み込む

FuelPHPのLogクラスは内部で、Monologを使用している。
MonologにはHandlersという仕組みでログの出力先をカスタマイズできる仕組みがあり、Rollbarにも対応している。

参考:monolog の Handler を追加する場合の記述場所 – Google グループ

前提

  1. Rollbarのアカウントを作成し、プロジェクトを作成する。
  2. https://rollbar.com/アカウント名/プロジェクト名/settings/access_tokens/ を参照して post_server_item のアクセストークンをメモしておく(※)

手順

fuel/app/bootstrap.phpを編集して末尾に以下を加える

$rollbar_config = array(
    'access_token' => 'POST_SERVER_ITEM_ACCESS_TOKEN',
    'environment' => \Fuel::$env,
);
\Log::instance()->pushHandler(new \Monolog\Handler\RollbarHandler(
        new RollbarNotifier($rollbar_config), \Monolog\Logger::NOTICE
));

POST_SERVER_ITEM_ACCESS_TOKENは※で取得したトークンに置き換える。

これにより、\Log::warning()や\Log::error()やFuelPHP上で発生したPHPエラーがRollbarにも出力されるようになる。

Heroku上のPHPアプリケーションにBASIC認証を導入する

Heroku上でnginxをWEBサーバとしたPHPアプリケーションに対してBASIC認証をかける

流れ

  • BASIC認証の設定はnginxの設定ファイルに記述
  • IDやパスワードは環境変数に登録
  • htpasswdファイルはデプロイ時に生成

前提

ディレクトリの初期構成は以下の通り。

public/
    index.php
vendor/
composer.json
Procfile

composer.jsonは

{
    "require-dev": {
        "heroku/heroku-buildpack-php": "*"
    }
}

として、composer install or updateをして、vendor/binディレクトリにvendor/bin/heroku-php-nginxがインストールされている。

Procfileは

web: bin/heroku-php-nginx public

として、ドキュメントルートをpublicフォルダとしてデプロイしている。

手順

  1. 環境変数にBASIC認証アカウントを登録
    $ heroku config:set BASIC_AUTH_USERNAME="basic_auth_user"
    $ heroku config:set BASIC_AUTH_PASSWORD="basic_auth_pass"
    

    またはWEBコンソール (https://dashboard.heroku.com/apps/APPNAME/settings) で追加する

  2. nginxにBASIC認証の設定を加えるため、設定の追加をする

    1. 設定用のフォルダを作成する
      $ mkdir heroku
      $ cd heroku
      
    2. nginx_app.confというファイルを作成する。すでにある場合は、auth_basic,auth_basic_user_fileの部分を追記する
      location / {
          auth_basic            "Restricted";
          auth_basic_user_file  $document_root/../.htpasswd;
      }
      

      このサンプルではルート下すべてをBASIC認証の領域とする。

    3. Procfileを編集して、デプロイ時にnginx_app.confを読み込むませる

      web: bin/heroku-php-nginx -C heroku/nginx_app.conf public
      
  3. Herokuの.profile.dの仕組みを使って、htpasswdファイルを生成するbashスクリプトを追加する
    $ mkdir .profile.d
    $ cd .profile.d
    $ vi gen-htpasswd.sh
    

    gen-htpasswd.shは

    #!/usr/bin/env bash
    set -ex
    
    echo -e "${BASIC_AUTH_USERNAME}:$(perl -le 'print crypt($ENV{"BASIC_AUTH_PASSWORD"}, rand(0xffffffff));')" > /app/.htpasswd
    
  4. Herokuにデプロイする

参考

開発環境と本番環境のPHPバージョンが違う状況で本番環境でcomposer installをした際にエラー

前提

  • 使用フレームワークはFuelPHP
  • 開発環境はPHP5.5.9(Vagrant&Docker)、本番環境はPHP5.4.45(さくらのレンタルサーバ)
  • サードパーティライブラリはcomposerを使用、composer.json,composer.lockをバージョン管理に含めている
  • デプロイサーバがあり、そこからデプロイができるようになっている
  • デプロイはデプロイサーバでgit pullしたものをrsyncで本番サーバに配布、その後本番サーバ上でcomposer installでサードパーティライブラリをインストールする手順

状況

composer.jsonのrequireに指定されている、nesbot/carbonに依存しているsymfony/translationがv3.0.0にバージョンアップした結果、PHPが5.5.9以上を要求されるようになった。

開発環境でcomposer instalやupdateをし、生成されたlockファイルをリポジトリに含めているため、デプロイでcomposer installを行うとlockファイルに記述されているバージョンを使用してインストールを行う
その結果以下のようなエラーとなった

Installing dependencies (including require-dev) from lock file
Your requirements could not be resolved to an installable set of packages.
 Problem 1
   - Installation request for symfony/translation v3.0.0 -> satisfiable by symfony/translation[v3.0.0].
   - symfony/translation v3.0.0 requires php >=5.5.9 -> your PHP version (5.4.45) or "config.platform.php" value does not satisfy that requirement.
 Problem 2
   - Installation request for symfony/console v3.0.0 -> satisfiable by symfony/console[v3.0.0].
   - symfony/console v3.0.0 requires php >=5.5.9 -> your PHP version (5.4.45) or "config.platform.php" value does not satisfy that requirement.
 Problem 3
   - Installation request for symfony/yaml v3.0.0 -> satisfiable by symfony/yaml[v3.0.0].
   - symfony/yaml v3.0.0 requires php >=5.5.9 -> your PHP version (5.4.45) or "config.platform.php" value does not satisfy that requirement.
 Problem 4
   - symfony/translation v3.0.0 requires php >=5.5.9 -> your PHP version (5.4.45) or "config.platform.php" value does not satisfy that requirement.
   - nesbot/carbon 1.21.0 requires symfony/translation ~2.6|~3.0 -> satisfiable by symfony/translation[v3.0.0].
   - Installation request for nesbot/carbon 1.21.0 -> satisfiable by nesbot/carbon[1.21.0].

一方、本番サーバー上でlockファイルを削除したのちcomposer installを行うとPHP5.4.45に対応しているsymfony/translationのv2.8.0がインストールされるため正常に終了できる。

解決

開発と本番でPHPのバージョンを合わせる以外の方法として、

PHP – あんまり知られてないけど有用な composer の機能 – Qiitaより、

開発環境側で、composer.jsonのconfig部分に

  "config": {
    "platform": {
        "php": "5.4.45"
    }
  }

とplatform.phpキーを追加し、本番環境のPHPバージョンを記述することで、開発環境でもcomposerで導入されるサードパーティのバージョンがPHP5.4.45に合わせたものになる。
composer updateしてcomposer.lockを更新したのち、composer.json,composer.lockをコミットして、同じようにデプロイ手順を行った結果正常にデプロイできました。

FuelPHP+Authパッケージ&Opauthでopauth/facebookのforkしたものを使う

FuelPHP上で認証機能を実装するために、Authパッケージ+Opauthドライバを利用する。

  1. はじめに – Opauth – Auth Package – FuelPHP Documentationを参考に、composerでopauth/opauth,opauth/facebookパッケージをインストール
  2. Opauth Controller example – Auth Package – FuelPHP Documentationを参考に、Authコントローラーを作成
  3. 開発者向けFacebookでFacebookアプリを作成
  4. fuel/app/config/opauth.phpを作成して
    return array(
        'Strategy' => array(
            'Facebook' => array(
                'app_id' => 'App ID',
                'app_secret' => 'App Secret',
                'scope' => array('email')
            ),
        )
    );

としてログイン画面を作成しましたが、Facebookからのコールバックでパラメータからメールアドレスが取得できませんでした。
これは、FacebookAPIの仕様変更によるもので、対応するにはopauth/facebook内のコードを編集する必要があります。

今回は、opauth/facebook内のコードを直接編集するのではなく、opauth/facebookをForkしてFacebook APIに対応したリポジトリを利用します。
リポジトリの選択は、「Network Graph · opauth/facebookから、オリジナルの最先端にある1.0ブランチから派生しているもので、派生先のmasterブランチに修正がコミットされたのが最近のもの」として、TippingCanoe/facebookを利用することにしました。

  1. composer.jsonを編集して
    repositoriesに

       { "type": "vcs", "url": "https://github.com/TippingCanoe/facebook" }
    

    を追加
    requireのopauth/facebookを

      "opauth/facebook": "dev-master"
    

    に変更したのち、composer updateを実行

  2. fuel/vendor/opauth/facebook/FacebookStrategy.phpを開いて、
    https://github.com/TippingCanoe/facebook/commit/3624b3043bf1ca5b87294aace7fd4df20ee2f8e4#diff-d286e64409257a85e4a8ea5c5f295e48
    の修正が適用されているかを確認

参考

ownCloud8をアップデートしたら、管理画面に”The test with getenv(“PATH”) only returns an empty response.”と表示されたとき

環境

の状態で、yum updateでownCloudを8.1.1にした結果、管理画面に

php does not seem to be setup properly to query system environment variables. The test with getenv("PATH") only returns an empty response.
Please check the installation documentation for php configuration notes and the php configuration of your server, especially when using php-fpm.

が表示された。

ownCloud 8.1: The test with getenv(“PATH”) only returns an empty response. – Techish.net
より
/etc/php-fpm.d/www.conf

clear_env = noの行のコメントアウトをはずして再読み込みすると解消する。

@@ -367,7 +367,7 @@
 ; Setting to "no" will make all environment variables available to PHP code
 ; via getenv(), $_ENV and $_SERVER.
 ; Default Value: yes
-;clear_env = no
+clear_env = no