2

プライベートメンバーを持つPHPクラスをMongoDbに保存する解決策があるかどうか、誰か教えてもらえますか? 次のエラーが発生し続けます

zero-length keys are not allowed, did you use $ with double quotes?'

実際の回答がない同じ質問に関連する既存の質問が少なくとも 2 つあります。
質問 1 質問 2

私のすべての永続化クラスには、利用できる必要があるプライベート メンバーがありますが、これはプライベート メンバーを利用する複数の機能を持つインスタンス ベースのクラスであるため、プライベート メンバーの必要性を回避する関数の作成には興味がありません。

Web サーバー Apache/2.2.22

PHP バージョン PHP 5.4.6

PHP 拡張機能 mongo/1.2.6

これはサンプル実装になります。コード自体を批判しないでください。これは、基本型の $this と $private メンバーの保存である動作の種類を説明するためのものです。

<?php

class PersistableObject extends AbstractBasePersistableObject
{
   public  $PublicSubTypeProperty;

    public function __construct()
    {
       parent::__construct();
    }

    public function GetDalConfigurationFromSubType()
    {
        //This object is just a wrapper DAL implemented based on
        //the php Mongo, MongoDb and MongoCollection objects
        return new MongoBasedDal();
    }
}


abstract class AbstractBasePersistableObject
{
   private $dalRef = null;
   public $PublicBaseProperty;

   public abstract function GetDalConfigurationFromSubType();

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

   public function Save()
   {
       $this->dalRef->Save($this);
   }
}

?>
4

2 に答える 2

5

プライベートメンバーを持つPHPクラスをMongoDbに保存する解決策があるかどうか、誰か教えてもらえますか?

問題は、Google グループからわかるように、PHP ドライバーが実際にはプライベート変数と保護された変数を保存から省略していることです。これは、ドライバー自体のコア内にある基本的な問題であるため、簡単に回避する方法はありません。ご存じのとおり、Derick はこのために JIRA を作成しました: https://jira.mongodb.org/browse/PHP-624

@harald は、独自の _to_array() を作成し、それを save 関数にフィードする方法を実際に述べていますが、残念ながら、これはクラスの構築方法に関する根本的な問題を再び引き起こします。これには次のようにリフレクションを使用する必要があります。

$reflect = new ReflectionClass(get_class($this));
$class_vars = $reflect->getProperties(ReflectionProperty::IS_PUBLIC | ReflectionProperty::IS_PROTECTED | ReflectionProperty::IS_PRIVATE);

foreach ($class_vars as $prop) {
    $doc[$prop->getName()] = $this->{$prop->getName()};
}

そして$doc、セーブ内で使用します。

$schemaただし、保存するすべてのフィールドを格納する定義済みの配列を作成することで、プログラミングを少し変更してリフレクションを回避することができます (または、リフレクションの結果をキャッシュしてリソースを大量に消費しないようにすることができます)。新しいフィールドをオンデマンドで追加したい場合は、メモリ内スキーマ配列を作成して更新するだけ__setです__get。このようにして、リフレクションを完全に回避し、スキーマ配列とその値を取得するだけです。

これは、Lithium、Yii、Kohona、CakePHP など、多くのフレームワークが問題を回避するために使用する方法です。

于 2012-12-07T09:43:24.370 に答える
1

問題は、Mongo がオブジェクトを配列にキャストしようとしている可能性があります。の出力を表示している場合...

class Address{
    private $name;
    private $company;
    private $zip;

    public function __construct($name,$company,$zip){
        $this->name = $name;
        $this->company = $company;
        $this->zip = $zip;
    }
}

print_r((array)new Address('name', 'company', 'zip'));

... hexdump を使用すると、次のことが明らかになります。

harald:$ ~/test.php | hexdump -C
00000000  41 72 72 61 79 0a 28 0a  20 20 20 20 5b 00 41 64  |Array.(.    [.Ad|
00000010  64 72 65 73 73 00 6e 61  6d 65 5d 20 3d 3e 20 6e  |dress.name] => n|
00000020  61 6d 65 0a 20 20 20 20  5b 00 41 64 64 72 65 73  |ame.    [.Addres|
00000030  73 00 63 6f 6d 70 61 6e  79 5d 20 3d 3e 20 63 6f  |s.company] => co|
00000040  6d 70 61 6e 79 0a 20 20  20 20 5b 00 41 64 64 72  |mpany.    [.Addr|
00000050  65 73 73 00 7a 69 70 5d  20 3d 3e 20 7a 69 70 0a  |ess.zip] => zip.|
00000060  29 0a                                             |).|
00000062

.Address.name のドットを見てください。これらは null バイトであり、おそらくキーでは許可されていないため、奇妙なエラー メッセージが表示されます。

PHP には (まだ) マジック メソッド __to_array がないため、オブジェクトを配列に「キャスト」する独自のヘルパー メソッドが必要になるでしょう。「パブリック」プロパティを使用することもできますが、これも良い解決策ではありません。

于 2012-11-30T08:54:03.443 に答える