2010年12月20日

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


今回はautoExecute文を使用して切り分けをしてみた。
現象は、OSコマンドでプログラムを実行する。問題はないのだが、
WEBから実行すると「MDB2 Error: unknown error」のエラー
が返り実行できない。
OSとWEB上の違いはheader("content-type","html/text");
だけです。
切り分けた結果は、common.phpのquit関数

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://digisys:digisys@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-tp30496061p30496061.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月20日 14:20
役に立ちました?:
過去のフィードバック 平均:(0) 総合:(0) 投票回数:(0)
本記事へのTrackback: http://hoop.euqset.org/blog/mt-tb2006.cgi/100837
トラックバック
コメント
コメントする




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