【问题标题】:Fatal PHP error bind paramater function致命的PHP错误绑定参数函数
【发布时间】:2014-06-12 15:39:58
【问题描述】:

我正在运行这个 PHP 脚本,但出现以下错误:

PHP 致命错误:在第 16 行的 c:/test.php 中的非对象上调用成员函数 bind_param()

第 16 行是:

$load_stmt->bind_param('ss', $filetobeloaded, $filetobeloaded);

谁能告诉我这句话有什么问题?

完整脚本:

<?php
$mysqli = new mysqli('localhost', 'root', 'password', 'orangevalleedb');
/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}
$file_query = "select filename from cdr";
$load_query = "LOAD DATA INFILE ? INTO TABLE cdr FIELDS TERMINATED BY ',' ENCLOSED BY '\"' LINES TERMINATED BY '\\n' ( @col_1, @col_2 )";

$file_stmt = $mysqli->prepare($file_query);
$file_stmt->execute();
$file_stmt->bind_result($filetobeloaded);

$load_stmt = $mysqli->prepare($load_query);
$load_stmt->bind_param('ss', $filetobeloaded, $filetobeloaded);

/* execute prepared statement */
while($file_stmt->fetch()) {
    $load_stmt->execute();
}

/* close statement and connection */
$load_stmt->close();
$file_stmt->close();

/* close connection */
$mysqli->close();
?>

【问题讨论】:

  • 可能是复制和粘贴错误。我已经解决了。
  • 你试过var_dump($load_stmt)看看你得到了什么?
  • 如错误消息所述,$load_stmt 不是对象。您的 SQL 查询中可能有错误。

标签: php sql


【解决方案1】:

我认为你不能在查询的那部分有一个绑定标记,正如官方 mysqli_prepare 文档中所解释的那样:

标记仅在 SQL 语句中的某些地方是合法的。为了 例如,它们在 INSERT 语句的 VALUES() 列表中是允许的 (指定行的列值),或与 WHERE 子句中的列来指定比较值。`

但我可能错了。

【讨论】:

  • 正确。 LOAD DATA 需要将文件名设置为文字字符串。检查我对官方文档页面的解释。
  • @JakeGould 感谢您的确认,真的不是 100% 确定。
【解决方案2】:

这是有用的信息,而不是答案。

根据MySQL 5.0 documentation,这些是唯一可以“准备”的语句。

遗憾的是,在不常见的版本 6+ 之前它并没有太大变化。

取自手册。

准备好的语句中可以使用以下 SQL 语句:

ALTER TABLE
CALL
COMMIT
{CREATE | DROP} INDEX
{CREATE | DROP} TABLE
DELETE
DO
INSERT
RENAME TABLE
REPLACE
SELECT
SET
SHOW (most variants)
TRUNCATE TABLE
UPDATE

从 MySQL 5.0.15 开始,支持以下附加语句:

{CREATE | DROP} VIEW

从 MySQL 5.0.23 开始,支持以下附加语句:

ANALYZE TABLE
OPTIMIZE TABLE
REPAIR TABLE

MySQL 5.0 不支持其他语句。

【讨论】:

    【解决方案3】:

    您不能在查询中这样做:

    $load_query = "LOAD DATA INFILE ? INTO TABLE…"
    

    正如MySQL官方documentation on LOAD DATA page中解释的那样;强调我的:

    文件名必须以字符串形式给出。在 Windows 上,指定 路径名称中的反斜杠作为正斜杠或双反斜杠。 character_set_filesystem 系统变量控制 文件名的解释。

    因此,您应该将该语句更改为:

    $load_query = "LOAD DATA INFILE $filetobeloaded INTO TABLE cdr FIELDS TERMINATED BY ',' ENCLOSED BY '\"' LINES TERMINATED BY '\\n' ( @col_1, @col_2 )";
    

    此外,我们在第 16 行的绑定语句有两个值:

    $load_stmt->bind_param('ss', $filetobeloaded, $filetobeloaded);
    

    但是被绑定的查询字符串只有一个?

    $load_query = "LOAD DATA INFILE ? INTO TABLE cdr FIELDS TERMINATED BY ',' ENCLOSED BY '\"' LINES TERMINATED BY '\\n' ( @col_1, @col_2 )";
    

    不清楚为什么bind_param 中有两个值,所以也许只需将其设置为一个参数即可:

    $load_stmt->bind_param('s', $filetobeloaded);
    

    【讨论】:

    • 不,它不会像它所说的那样 $load_stmt 不是一个对象..不管有多少参数。
    • 抱歉,完整的语句如下: $load_query = "LOAD DATA INFILE ? INTO TABLE cdr FIELDS TERMINATED BY ',' ENCLOSED BY '\"' LINES TERMINATED BY '\\n' SET filename = ? ";
    • @user3556262 看看我的回答。问题是您在使用LOAD DATA 时无法参数化文件的名称/路径。您需要将其设置为纯字符串。
    猜你喜欢
    • 2020-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-20
    • 2014-07-21
    • 2016-07-02
    • 1970-01-01
    • 2016-11-21
    相关资源
    最近更新 更多