2017-02-07 3 views
1

社内でAPIを呼び出す際に問題が発生しました。 ログは言う:私はちょっと迷ってしまいましたsymfony注意:unserialize():40のオフセット36でエラーが発生し、MysqlからPostgreSQLに移動しました

[2017-02-07 16:04:39] doctrine.DEBUG: SELECT h0_.id AS id_0, h0_.hash AS hash_1, h0_.request AS request_2, h0_.options AS options_3, h0_.serialized_response_body AS serialized_response_body_4, h0_.response AS response_5, h0_.sent_at AS sent_at_6 FROM http_request h0_ WHERE h0_.hash = ? ["dd3e36a5a38618974cae2b45f9cb3a67"] [] 
[2017-02-07 16:04:39] request.CRITICAL: Uncaught PHP Exception Symfony\Component\Debug\Exception\ContextErrorException: "Notice: unserialize(): Error at offset 36 of 40 bytes" at /var/www/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/ObjectType.php line 57 {"exception":"[object] (Symfony\\Component\\Debug\\Exception\\ContextErrorException(code: 0): Notice: unserialize(): Error at offset 36 of 40 bytes at /var/www/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/ObjectType.php:57)"} [] 

>を。 <

EDIT:私のコントローラで

、私は、プロセスを実行するために、いくつかの情報を含むフォームを送信します。

/** 
* @Rest\View(serializerGroups={"Review"}) 
* @Security("is_granted('ROLE_REVIEW_CREATE')") 
*/ 
public function postAction(Request $request) 
{ 
    if ($this->getUser()->getBalance()->getTokens() == 0) { 
     throw new AccessDeniedException('The Review can not be created because you lack of tokens'); 
    } 

    $review = new Review(); 
    $review->setCreatedBy($this->getUser()); 

    $reviewForm = $this->createForm(ReviewType::class, $review, [ 
     'csrf_protection' => false, 
    ]); 
    $reviewForm->submit($request->request->all()); 
    if ($reviewForm->isSubmitted() && $reviewForm->isValid()) { 
     // If the user is in an organization, takes the organization analyzer environment, otherwise takes the user one. 
     $analyzerEnvironment = $this->getUser()->getCompany() ? $this->getUser()->getCompany()->getAnalyzerEnvironment() : $this->getUser()->getAnalyzerEnvironment(); 

     $crawlingFlow = $this->get('app.manager.crawling_flow')->getCrawlingFlow(); 

     $this->get('app.manager.review')->process(
      $review, 
      $crawlingFlow, 
      $analyzerEnvironment 
     ); 

     $reviewEncrypted = new ReviewEncrypted(); 
     $reviewEncrypted->setReliability($review->getReliability()); 
     $reviewEncrypted->setData($this->get('app.manager.review')->encrypt($review)); 
     $reviewEncrypted->setCreatedBy($this->getUser()); 
     $this->getDoctrine()->getManager()->persist($reviewEncrypted); 
     $this->getDoctrine()->getManager()->flush(); 
     $review->setId($reviewEncrypted->getId()); 

     if ($this->getUser()->getBalance()->getTokens() > 0) { 
      $this->getUser()->getBalance()->setTokens($this->getUser()->getBalance()->getTokens() - 1); 
      $this->getDoctrine()->getManager()->persist($this->getUser()); 
      $this->getDoctrine()->getManager()->flush(); 
     } 

     return $review; 
    } 

    return $reviewForm; 
} 

アンを呼び出す:

$crawlingFlow = $this->get('app.manager.crawling_flow')->getCrawlingFlow(); 

    $this->get('app.manager.review')->process(
     $review, 
     $crawlingFlow, 
     $analyzerEnvironment 
    ); 

いくつかのサービスが呼ばれて、彼らは私が忘れてしまった何かがある...

質問があるなど、DBに保存するようなものを行うには、要求を送信します私がdb(mysqlからpostgresqlへ)を変更したときや、それは何か他のものですか?

unserialize()エラーはどこに来る可能性がありますか?どうして ?助けのための

ありがとう:P

EDIT 2:エラーログ「ベンダー/ドクトリン/ DBAL/libに/ドクトリン/ DBAL /種類/ ObjectType.phpラインに従っから来てここで

57" :

/** 
* {@inheritdoc} 
*/ 
public function convertToDatabaseValue($value, AbstractPlatform $platform) 
{ 
    return serialize($value); 
} 

/** 
* {@inheritdoc} 
*/ 
public function convertToPHPValue($value, AbstractPlatform $platform) 
{ 
    if ($value === null) { 
     return null; 
    } 

    $value = (is_resource($value)) ? stream_get_contents($value) : $value; 
    $val = unserialize($value); 
    if ($val === false && $value !== 'b:0;') { 
     throw ConversionException::conversionFailed($value, $this->getName()); 
    } 

    return $val; 
} 
+0

あなたのコードについて何か? – Random

+0

データが役立つ可能性があります。 – AbraCadaver

+0

残念なことに投稿編集 –

答えて

0

ありのMySQLとPostgreSQLのtext間に1つの重要な違いがあり、そしてそれはあなたのケースだかもしれません。 PostgreSQLはテキストフィールドで\ 0を許可しません。だから、準備段階で最初の\ 0にドライバをカットします。

残念ながら、serializeは\ 0記号を内部的に使用します。

class A { 
    private $a = 'a'; 
    private $b = 'b'; 
} 

$a = new A(); 

var_export(serialize($a)); 

この刺すの 'O:1:"A":2:{s:4:"' . "\0" . 'A' . "\0" . 'a";s:1:"a";s:4:"' . "\0" . 'A' . "\0" . 'b";s:1:"b";}'

MySQLの挿入が正常に動作しますが表示されます: INSERT INTO test1 VALUES ('O:1:\"A\":2:{s:4:\"\0A\0a\";s:1:\"a\";s:4:\"\0A\0b\";s:1:\"b\";}')

しかし、Pgのドライバ静かにカットした文字列と準備をして
LOG: execute pdo_stmt_00000001: INSERT INTO test1 VALUES ($1)
DETAIL: parameters: $1 = 'O:1:"A":2:{s:4:"'
またはINSERT INTO test1 VALUES ('O:1:"A":2:{s:4:"')を実行しますエミュレーション。

あなたが見る通り、結果は文字列をカットし、unserializeは復元できません。

解決方法:Postgresqlにbyteaデータ型を使用するか、シリアル化された文字列のエンコード/デコードを追加してください。

UPD:教義http://docs.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/types.html#objectで約objectデータ型

+0

Thy、bytea方法を実装する方法に関するいくつかの調査をしています –

関連する問題