2015-09-30 17 views
9

Doctrine2型を使用してデータベース値を暗号化しています。この型は、内部的にPHP値を暗号化および復号化することにより、データベース値との間で変換します。これはDoctrine2型のために完全に機能します。Doctrine型を使用して同じPHP値でデータベース値を更新する

暗号化は、base64でエンコードされた文字列として格納されます。すべての暗号化された文字列には、固定の定義済み接頭辞が前置されます。つまり、データベースフィールドには暗号化された値と復号化された値(外部要件によって必要とされる)が含まれ、接頭辞によって認識されます。


私の願いは、以下の通りです:

私は実体を持っていると仮定します。 Doctrineを使ってエンティティのすべてのプロパティの暗号化または復号化を強制したい。これを行うには、型内のデータベース値を暗号化された形式または復号化された形式で保存する必要があります。

ただし、メソッドEntityManager::computeChangeSetsを呼び出すと、エンティティのプロパティは変更されていません。もちろん、実際のデータ(PHP値)は変更されません。ただし、データベースの値は変更される予定です。

これを行う方法は?


Doctrineのタイプのいくつかのコード:私はすべての不要なコードを削除した

<?php 

use Doctrine\DBAL\Types\Type; 

class EncryptedType extends Type { 

    private static $forceDecrypt = false; 

    // Encryption stuff, like encrypt() and decrypt() 

    public function convertToPHPValue($value, AbstractPlatform $platform) { 
     if ($value === null) { 
      return null; 
     } 
     return $this -> decrypt($value, false); 
    } 

    public function convertToDatabaseValue($value, AbstractPlatform $platform) { 
     if ($value === null) { 
      return null; 
     } 
     if (self::$forceDecrypt) { 
      return (string) $value; 
     } 
     return $this -> encrypt((string) $value, false); 
    } 
} 

答えて

0

ドクトリンコードに何時間もダイビングした後、私自身の質問に対する答えが見つかりました。

私の解決策の概要は以下のとおりです。


まず、すべてのタイプのPHP値を保持できる単純な値クラスを作成しました。元の値に戻す方法は__toString()です。

コード:

class Value { 
    private $value; 

    public function __construct($value) { 
     $this -> value = $value; 
    } 

    public function __toString() { 
     return $this -> value; 
    } 
} 

EncryptedTypeクラスはまったく同じままです。ポイントはエンティティの値です。クラスのプロパティをデータベースに強制更新される(したがってEncryptedTypeクラスを利用する)必要がある場合、それは次のように設定されます。

foreach (self::$properties as $property) { 
    $value = $accessor -> getValue($entity, $property); 
    if ($value !== null) { 
     $accessor -> setValue($entity, $property, new Value($value)); 
    } 
} 

$accessorは、プロパティアクセサです。)

new Value(...)ラッパーは、Doctrineがプロパティ値の変更に気づき、データベースを変更することに注意してください。もちろん、値は__toString()メソッドから取得されます。これは私たちが必要とするものです。

2

バグではありませんか?

回避方法:エンティティがマネージャによって管理されていて、状態がSTATE_MANAGEDの場合、STATE_NEWに変更して強制的に更新すると、問題が解決されます。

+1

私はそうは思わない。Doctrineは 'EncryptedType'クラスの静的フィールドの変更についてどのように知っていますか?私はDoctrineイベントを使ってこれを解決しなければならないのではないかと心配しています。 –

関連する問題