2010年12月23日

[PHP-users 35466] Re:再投稿 WEBからMDB2のexecute文が実行できない


もう少し詳細エラー出力すようにテストプログラムを改造した。

require_once 'PEAR/ErrorStack.php';
class test1 extends test_db {
protected $mdb2;

// コンストラクタ

function __construct($db_name = 'test_db'){
$this->mdb2 = parent::__construct($db_name);
}

function add(){
$errorStack = new PEAR_ErrorStack('TEST_MDB2');
$errorStack->pushCallback(array($this,'handleError'));
$types = array('text','text','integer');
$fields_values = array( 'test_char' => '90001111',
'test_varchar' => 'テスト',
'test_integer' => 1
);
$result =
$this->mdb2->db->autoExecute('test_table',$fields_values,MDB2_AUTOQUERY_INSERT,
null, $types);
if(MDB2::isError($result)){
$errorStack->push(
1,
'error',
array(
$result->getMessage() . "<br>",
$result->getUserInfo() . "<br>",
$result->getDebugInfo() . "<br>"
),
$result->getMessage() . "<br>"
);
return;
}
return "DB_OK";
}
function handleError($err)
{
print_r($err);
}

出力は
Array ( [code] => 1 [params] => Array ( [0] => MDB2 Error: unknown error
[1] => _doQuery: [Error message: Could not execute statement] [Last executed
query: EXECUTE
mdb2_statement_pgsql_1a50a539ebab33432c575e52a2ee0ba16836df92e ('90001111',
'テスト', 1)] [Native message: ]
[2] => _doQuery: [Error message: Could not execute statement] [Last executed
query: EXECUTE
mdb2_statement_pgsql_1a50a539ebab33432c575e52a2ee0ba16836df92e ('90001111',
'テスト', 1)] [Native message: ]
) [package] => TEST_MDB2 [level] => error [time] => 1293102774.8693
[context] => Array ( [file] => /home/test/db_class.php [line] => 57
[function] => add [class] => test1 ) [message] => MDB2 Error: unknown error
)

sakon wrote:
>
> 今回はautoExecute文を使用して切り分けをしてみた。
> 現象は、OSコマンドでプログラムを実行すると問題はないのだが、
> WEBから実行すると「MDB2 Error: unknown error」のエラー
> が返り実行できない。
> OSとWEB上の違いはheader("content-type","html/text");
> だけです。
> 切り分けた結果は、common.phpのqouteメソッド
> if(PEAR::isError($db)) {return $db;}と同じく_quoteTextメソッドの
> if(PEAR::isError($db)) {return $db;}でエラーが発生してreturn文
> が実行されています。コメントアウトをすると正常に動作します。
> 仕事が忙しくisErrorの中身まで調べてきれていませんアドバイスを
> お願いします。
> (1)環境
> CentOS release 5.3 (Final)
> PHP 5.1.6
> MDB2 2.5.0b2-beta
> MDB2_Driver_pgsql 1.5.0b2-beta
> (2)試験DB環境 
> POSTGRESQL 8.1
> psql -l
> List of databases
> Name | Owner | Encoding
> -----------------------+----------+----------
> test_db | postgres | EUC_JP
>
> test_db=# select * from test_table;
> test_char | test_varchar | test_integer
> -----------+--------------+--------------
> 90001111 | テスト | 1
> (1 row)
>
> (3)試験プログラム
> <?php
> require_once("MDB2.php");
>
> // エラーハンドラ
> class test_db {
> const DSN = "pgsql://xxxxx:xxxxx@xxxxx(localhost:5432)/";
> protected $db;
>
> // コンストラクタ
> function __construct($db_name){
> $dsn = self::DSN . $db_name;
> $options = array('debug'=>2,'result_buffering' => false);
> $con =& MDB2::factory($dsn,$options);
> if(PEAR::isError($con)){
> die($con->getMessage());
> }
> $con->loadModule('Extended');
> $con->setFetchMode(MDB2_FETCHMODE_ASSOC);
> $this->db = $con;
> return $this;
> }
> }
> class test1 extends test_db {
> protected $mdb2;
>
> // コンストラクタ
> function __construct($db_name = 'test_db'){
> $this->mdb2 = parent::__construct($db_name);
> }
>
> function add(){
> $types = array('text','text','integer');
> $fields_values = array( 'test_char' => '90001111',
> 'test_varchar' => 'テスト',
> 'test_integer' => 1
> );
> $result =
> $this->mdb2->db->autoExecute('test_table',$fields_values,MDB2_AUTOQUERY_INSERT,
> null, $types);
> if(PEAR::isError($result)){
> return $result->getMessage();
> }
> return "DB_OK";
> }
> }
> $db = new test1();
> $ret=$db->add();
> header("content-type","html/text");
> print_r($ret);
> ?>
>
> (4)エラー追跡結果
> ?autoExecute関数
> MDB2/Extended.php
> function &autoExecute($table, $fields_values, $mode =
> MDB2_AUTOQUERY_INSERT,
> $where = false, $types = null, $result_class = true, $result_types
> = MDB2_PREPARE_MANIP)
> {
> $fields_values = (array)$fields_values;
> if ($mode == MDB2_AUTOQUERY_SELECT) {
> if (is_array($result_types)) {
> $keys = array_keys($result_types);
> } elseif (!empty($fields_values)) {
> $keys = $fields_values;
> } else {
> $keys = array();
> }
> } else {
> $keys = array_keys($fields_values);
> }
> $params = array_values($fields_values);
> if (empty($params)) {
> $query = $this->buildManipSQL($table, $keys, $mode, $where);
>
> $db =& $this->getDBInstance();
> if (PEAR::isError($db)) {
> return $db;
> }
> if ($mode == MDB2_AUTOQUERY_SELECT) {
> $result =& $db->query($query, $result_types,
> $result_class);
> } else {
> $result = $db->exec($query);
> }
> } else {
> $stmt = $this->autoPrepare($table, $keys, $mode, $where,
> $types, $result_types);
> if (PEAR::isError($stmt)) {
> return $stmt;
> }
>        【以降からエラー発生】
> $result =& $stmt->execute($params, $result_class);
> $stmt->free();
> }
> return $result;
> }
> ?executeメソッド
> function &execute($values = null, $result_class = true, $result_wrap_class
> = false)
> {
> if (is_null($this->positions)) {
> return $this->db->raiseError(MDB2_ERROR, null, null,
> 'Prepared statement has already been freed',
> __FUNCTION__);
> }
>
> $values = (array)$values;
> if (!empty($values)) {
> $err = $this->bindValueArray($values);
> if (PEAR::isError($err)) {
> return $this->db->raiseError(MDB2_ERROR, null, null,
> 'Binding Values failed with
> message: ' . $err->getMessage(), __FUNCTION__);
> }
> }
>     【以降からエラー発生】
> $result =& $this->_execute($result_class, $result_wrap_class);
> return $result;
> }
>
> ?オーバーライド_executeメソッド
> MDB2/driver/pgsql.php
> class MDB2_Statement_pgsql extends MDB2_Statement_Common
> function &_execute($result_class = true, $result_wrap_class = false)
> {
> if (is_null($this->statement)) {
> $result =& parent::_execute($result_class,
> $result_wrap_class);
> return $result;
> }
> $this->db->last_query = $this->query;
> $this->db->debug($this->query, 'execute', array('is_manip' =>
> $this->is_manip, 'when' => 'pre', 'parameters' => $this->values));
> if ($this->db->getOption('disable_query')) {
> $result = $this->is_manip ? 0 : null;
> return $result;
> }
>
> $connection = $this->db->getConnection();
> if (PEAR::isError($connection)) {
> return $connection;
> }
>
> $query = false;
> $parameters = array();
> // todo: disabled until pg_execute() bytea issues are cleared up
> if (true || !function_exists('pg_execute')) {
> $query = 'EXECUTE '.$this->statement;
> }
> if (!empty($this->positions)) {
> foreach ($this->positions as $parameter) {
> if (!array_key_exists($parameter, $this->values)) {
> return $this->db->raiseError(MDB2_ERROR_NOT_FOUND,
> null, null,
> 'Unable to bind to missing placeholder:
> '.$parameter, __FUNCTION__);
> }
> $value = $this->values[$parameter];
> $type = array_key_exists($parameter, $this->types) ?
> $this->types[$parameter] : null;
> if (is_resource($value) || $type == 'clob' || $type ==
> 'blob' || $this->db->options['lob_allow_url_include']) {
> if (!is_resource($value) &&
> preg_match('/^(\w+:\/\/)(.*)$/', $value, $match)) {
> if ($match[1] == 'file://') {
> $value = $match[2];
> }
> $value = @fopen($value, 'r');
> $close = true;
> }
> if (is_resource($value)) {
> $data = '';
> while (!@feof($value)) {
> $data.= @fread($value,
> $this->db->options['lob_buffer_length']);
> }
> if ($close) {
> @fclose($value);
> }
> $value = $data;
> }
> }
>          【以降からエラー発生】
> $quoted = $this->db->quote($value, $type, $query);
> if (PEAR::isError($quoted)) {
> return $quoted;
> }
> $parameters[] = $quoted;
> }
> if ($query) {
> $query.= ' ('.implode(', ', $parameters).')';
> }
> }
>
> if (!$query) {
> $result = @pg_execute($connection, $this->statement,
> $parameters);
> if (!$result) {
> $err =& $this->db->raiseError(null, null, null,
> 'Unable to execute statement', __FUNCTION__);
> return $err;
> }
> } else {
> $result = $this->db->_doQuery($query, $this->is_manip,
> $connection);
> if (PEAR::isError($result)) {
> return $result;
> }
> }
>
> if ($this->is_manip) {
> $affected_rows = $this->db->_affectedRows($connection,
> $result);
> return $affected_rows;
> }
>
> $result =& $this->db->_wrapResult($result, $this->result_types,
> $result_class, $result_wrap_class, $this->limit,
> $this->offset);
> $this->db->debug($this->query, 'execute', array('is_manip' =>
> $this->is_manip, 'when' => 'post', 'result' => $result));
> return $result;
> }
> ?quoteメソッド
> MDB2/Driver/Datatype/common.php
> function quote($value, $type = null, $quote = true, $escape_wildcards =
> false)
> {
> $db =& $this->getDBInstance();
> 【 以降からエラー:下記の発生コメントアウトすればquoteTextメソッドからエラー】
> /*
> if (PEAR::isError($db)) {
> return $db;
> }
> */
> if (is_null($value)
> || ($value === '' && $db->options['portability'] &
> MDB2_PORTABILITY_EMPTY_TO_NULL)
> ) {
> if (!$quote) {
> return null;
> }
> return 'NULL';
> }
>
> if (is_null($type)) {
> switch (gettype($value)) {
> case 'integer':
> $type = 'integer';
> break;
> case 'double':
> // todo: default to decimal as float is quite unusual
> // $type = 'float';
> $type = 'decimal';
> break;
> case 'boolean':
> $type = 'boolean';
> break;
> case 'array':
> $value = serialize($value);
> case 'object':
> $type = 'text';
> break;
> default:
> if (preg_match('/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}$/',
> $value)) {
> $type = 'timestamp';
> } elseif (preg_match('/^\d{2}:\d{2}$/', $value)) {
> $type = 'time';
> } elseif (preg_match('/^\d{4}-\d{2}-\d{2}$/', $value)) {
> $type = 'date';
> } else {
> $type = 'text';
> }
> break;
> }
> } elseif (!empty($db->options['datatype_map'][$type])) {
> $type = $db->options['datatype_map'][$type];
> if (!empty($db->options['datatype_map_callback'][$type])) {
> $parameter = array('type' => $type, 'value' => $value,
> 'quote' => $quote, 'escape_wildcards' => $escape_wildcards);
> return
> call_user_func_array($db->options['datatype_map_callback'][$type],
> array(&$db, __FUNCTION__, $parameter));
> }
> }
>
> if (!method_exists($this, "_quote{$type}")) {
> return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null,
> 'type not defined: '.$type, __FUNCTION__);
> }
> $value = $this->{"_quote{$type}"}($value, $quote,
> $escape_wildcards);
> if ($quote && $escape_wildcards &&
> $db->string_quoting['escape_pattern']
> && $db->string_quoting['escape'] !==
> $db->string_quoting['escape_pattern']
> ) {
> $value.= $this->patternEscapeString();
> }
> return $value;
> }
> ?quoteTextメソッド
> MDB2/Driver/Datatype/common.php
> function _quoteText($value, $quote, $escape_wildcards)
> {
> if (!$quote) {
> return $value;
> }
>
> $db =& $this->getDBInstance();
> 【以降からエラー発生:quoteメソッドのコメントアウトと下記のコメントアウトすると正常に処理する】
> /*if (PEAR::isError($db)) {
> return $db;
> }
> */
> $value = $db->escape($value, $escape_wildcards);
> if (PEAR::isError($value)) {
> return $value;
> }
> return "'".$value."'";
> }
>
>

--
View this message in context: http://old.nabble.com/%E5%86%8D%E6%8A%95%E7%A8%BF%E3%80%80WEB%E3%81%8B%E3%82%89MDB2%E3%81%AEexecute%E6%96%87%E3%81%8C%E5%AE%9F%E8%A1%8C%E3%81%A7%E3%81%8D%E3%81%AA%E3%81%84-tp30496061p30520234.html
Sent from the Php Japan - PHP-users mailing list archive at Nabble.com.

_______________________________________________
PHP-users mailing list PHP-users@xxxxx
http://ml.php.gr.jp/mailman/listinfo/php-users
PHP初心者のためのページ - 質問する前にはこちらをお読みください

投稿者 xml-rpc : 2010年12月23日 20:30
役に立ちました?:
過去のフィードバック 平均:(0) 総合:(0) 投票回数:(0)
本記事へのTrackback: http://hoop.euqset.org/blog/mt-tb2006.cgi/100903
トラックバック
コメント
コメントする




画像の中に見える文字を入力してください。