Phalcon\DI\FactoryDefaultは何を登録するのか?

Phalcon\DI\FactoryDefaultは、Phalconに付属しているコンポーネントのほとんどを登録すると公式ドキュメントにあります。

ということで、実際に何を登録するのか確認してみます。

$di = new FactoryDefault();
var_dump($di); exit;
object(Phalcon\DI\FactoryDefault)[7]
  public '_services' => 
    array (size=21)
      'router' => 
        object(Phalcon\DI\Service)[8]
      'dispatcher' => 
        object(Phalcon\DI\Service)[9]
      'url' => 
        object(Phalcon\DI\Service)[10]
      'modelsManager' => 
        object(Phalcon\DI\Service)[11]
      'modelsMetadata' => 
        object(Phalcon\DI\Service)[12]
      'response' => 
        object(Phalcon\DI\Service)[13]
      'cookies' => 
        object(Phalcon\DI\Service)[14]
      'request' => 
        object(Phalcon\DI\Service)[15]
      'filter' => 
        object(Phalcon\DI\Service)[16]
      'escaper' => 
        object(Phalcon\DI\Service)[17]
      'security' => 
        object(Phalcon\DI\Service)[19]
      'crypt' => 
        object(Phalcon\DI\Service)[20]
      'annotations' => 
        object(Phalcon\DI\Service)[18]
      'flash' => 
        object(Phalcon\DI\Service)[21]
      'flashSession' => 
        object(Phalcon\DI\Service)[22]
      'tag' => 
        object(Phalcon\DI\Service)[23]
      'session' => 
        object(Phalcon\DI\Service)[24]
      'sessionBag' => 
        object(Phalcon\DI\Service)[25]
      'eventsManager' => 
        object(Phalcon\DI\Service)[26]
      'transactionManager' => 
        object(Phalcon\DI\Service)[27]
      'assets' => 
        object(Phalcon\DI\Service)[28]
  public '_sharedInstances' => 
    array (size=0)
      empty
  public '_freshInstance' => boolean false

Tags: phalcon

PhalconのDebugコンポーネントを使ってみる

PhalconにはDebugコンポーネントという例外をキャッチして見やすく表示してくれるやつが標準で付属しています。

ということで、使ってみようと思います。

phalconコマンドでsimpleなプロジェクトを作成し、変更します。

--- a/public/index.php
+++ b/public/index.php
@@ -2,7 +2,16 @@

 error_reporting(E_ALL);

-try {
+set_error_handler(
+    function ($errno, $errstr, $errfile, $errline) {
+        throw new ErrorException($errstr, $errno, 0, $errfile, $errline);
+    }
+);
+
+$debug = new \Phalcon\Debug();
+$debug->listen();
+
+//try {

     /**
      * Read the configuration
@@ -26,6 +35,6 @@ try {

     echo $application->handle()->getContent();

-} catch (\Exception $e) {
-    echo $e->getMessage();
-}
+//} catch (\Exception $e) {
+//    echo $e->getMessage();
+//}

これで準備ができました。

試しに、Noticeの出るコードをコントローラに書いてアクセスしてみます。

▼例外がキャッチされてバックトレースが表示されました。 Phalcon Debugコンポーネント

▼Serverタブ Phalcon Debugコンポーネント

▼Included Filesタブ Phalcon Debugコンポーネント

▼Memoryタブ Phalcon Debugコンポーネント

このようにDebugコンポーネントを使うと、エラーの発見がしやすくなります。

ただし、Debugコンポーネントは開発環境でのみ使うべきなので、本番環境では使用されないようなコードにする必要がありますね。

Tags: phalcon, debug

herokuでMySQL(ClearDB)をSSLで暗号化して使う

昨日の「herokuでPHPからMySQL(ClearDB)を使う」で

なお、SSL設定をしていませんので通信は暗号化されていませんので注意してください。

と書きました。

今日は、暗号化していない場合、MySQLはどんな通信をしているかを、パケットキャプチャして確認してみたいと思います。

ということで、mysqlコマンドでログインしてSQL文を発行してみます。

$ mysql --host=us-cdbr-iron-east-01.cleardb.net --user=b16d3f52562f99 --password=1dab1fd2 heroku_43749156d41f0d5
Warning: Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 22500816
Server version: 5.5.40-log MySQL Community Server (GPL)

Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> SELECT * FROM user;
+----+-------+---------------------+
| id | name  | data_created        |
+----+-------+---------------------+
|  1 | user1 | 2014-12-12 04:14:53 |
|  2 | user2 | 2014-12-12 04:15:01 |
|  3 | user3 | 2014-12-12 04:15:06 |
+----+-------+---------------------+
3 rows in set (0.20 sec)

mysql> 

上記の通信をWiresharkでキャプチャして確認してみます。

▼ユーザ名とデータベース名が見えてます。 MySQLの通信のパケットキャプチャ

▼発行したSQL文も見えてます。 MySQLの通信のパケットキャプチャ

▼SELECTの結果もすべて見えます。 MySQLの通信のパケットキャプチャ

はい、ということで、もし、パケットキャプチャが可能なら、ユーザ名、データベース名、発行したすべてのSQL文、そしてその結果セットのすべてを簡単に取得できます。

SSLの設定

herokunにログインし、AppsのResourceのAdd-onsの「ClearDB MySQL Database」をクリックします。

ClearDB Database Dashboardが表示されますので、SSL CertificatesからPEM FormatのClearDB CA Certificate(cleardb-ca.pem)をダウンロードします。

ClearDB Database DashboardのSSL Certificates

my.cnfの[client]セクションにダウンロードしたファイルを設定します。

[client]
ssl-ca   = /path/to/cleardb-ca.pem

これでmysqlコマンドからSSLが使えるようになります。接続し直して、以下のコマンドを実行してみます。

mysql> status;

SSLの値が以下のように「Cipher in use is DHE-RSA-AES256-SHA」に変わっており、暗号化通信になっていることがわかります。

SSL:            Cipher in use is DHE-RSA-AES256-SHA

あるいは、以下でもわかります。

mysql> SHOW STATUS LIKE 'ssl_cipher';
+---------------+--------------------+
| Variable_name | Value              |
+---------------+--------------------+
| Ssl_cipher    | DHE-RSA-AES256-SHA |
+---------------+--------------------+
1 row in set (0.20 sec)

PDOでの設定

以下のようにPDOのコンストラクタにPDO::MYSQL_ATTR_SSL_CAをオプションで指定します。

<?php

$db = parse_url($_SERVER['CLEARDB_DATABASE_URL']);
$db['dbname'] = ltrim($db['path'], '/');
$dsn = "mysql:host={$db['host']};dbname={$db['dbname']};charset=utf8";

$options = array(
    PDO::MYSQL_ATTR_SSL_CA   => __DIR__ . '/../ssl/cleardb-ca.pem'
);

try {
    $db = new PDO($dsn, $db['user'], $db['pass'], $options);
    $db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
    $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    $sql = "SHOW STATUS LIKE 'ssl_cipher'";
    $prepare = $db->prepare($sql);
    $prepare->execute();

    echo '<pre>';
    $prepare->execute();
    $result = $prepare->fetchAll(PDO::FETCH_ASSOC);
    print_r(h($result));
    echo "\n";
    echo '</pre>';
} catch (PDOException $e) {
    echo 'Error: ' . h($e->getMessage());
}

function h($var)
{
    if (is_array($var)) {
        return array_map('h', $var);
    } else {
        return htmlspecialchars($var, ENT_QUOTES, 'UTF-8');
    }
}

ブラウザからアクセスすると、以下のように「DHE-RSA-AES256-SHA」で暗号化通信していることがわかります。

Array
(
    [0] => Array
        (
            [Variable_name] => Ssl_cipher
            [Value] => DHE-RSA-AES256-SHA
        )

)

クライアント証明書を使う場合

ClearDB Database Dashboardから、SSL CertificatesのPEM FormatのClient CertificateとClient Private Keyをダウンロードします。

key.pemファイルをherokuで使えるように変換します。

$ openssl rsa -in b16d3f52562f99-key.pem -out cleardb_id-key-no-password.pem

my.cnfの[client]セクションに以下の設定を追加します。

[client]
ssl-key  = /etc/mysql/cleardb_id-key-no-password.pem
ssl-cert = /etc/mysql/b16d3f52562f99-cert.pem

PDOの場合は、以下のように追加します。

--- a/public/index.php
+++ b/public/index.php
@@ -5,7 +5,9 @@ $db['dbname'] = ltrim($db['path'], '/');
 $dsn = "mysql:host={$db['host']};dbname={$db['dbname']};charset=utf8";

 $options = array(
-    PDO::MYSQL_ATTR_SSL_CA   => __DIR__ . '/../ssl/cleardb-ca.pem'
+    PDO::MYSQL_ATTR_SSL_CA   => __DIR__ . '/../ssl/cleardb-ca.pem',
+    PDO::MYSQL_ATTR_SSL_KEY  => __DIR__ . '/../ssl/cleardb_id-key-no-password.pem',
+    PDO::MYSQL_ATTR_SSL_CERT => __DIR__ . '/../ssl/b16d3f52562f99-cert.pem',
 );

 try {

参考

関連

Tags: heroku, mysql, php, database