我有一个 PHP 脚本,它被分成两个单独的 PHP 脚本(因为它们每个都有一个目的并且很长)。为简单起见,我们将它们称为 1.php 和 2.php。
Script 1.php 对网站进行 API 调用,将有效负载传递给函数。一旦截断新记录并将其插入表中,它就会包含第二个脚本。这就是问题开始的地方。似乎当我查询 marketPlace 表时,它返回一个空数组,但是如果我在包含 2.php 之前插入一个 sleep(1) ,它就可以工作!我只能总结一下,在调用下一个查询之前,1.php 中的截断和插入查询以某种方式尚未完成? (我以前从未遇到过这种情况!)。
只有一个数据库连接,由1.php中包含的数据库类定义:
class Database
{
// This class allows us to access the database from any function with ease
// Just call it with Database::$conn
/** TRUE if static variables have been initialized. FALSE otherwise
*/
private static $init = FALSE;
/** The mysqli connection object
*/
public static $conn;
/** initializes the static class variables. Only runs initialization once.
* does not return anything.
*/
public static function initialize()
{
Global $servername;
Global $username;
Global $password;
Global $dbname;
try {
if (self::$init===TRUE)return;
self::$init = TRUE;
self::$conn = new mysqli($servername, $username, $password, $dbname);
}
catch (exception $e) {
date('Y-m-d H:i:s',time()) . " Cant' connect to MySQL Database - re-trying" . PHP_EOL;
}
}
public static function checkDB()
{
if (!mysqli_ping(self::$conn)) {
self::$init = FALSE;
self::initialize();
}
}
}
截断并插入市场的功能是:
function processMarketplace($marketData) {
// Decode to JSON
$outputj = json_decode($marketData, true);
$marketplaceCounter = 0;
// Check for success
if (($outputj['success']==true) && (!stristr($marketData, "error"))) {
// Create the blank multiple sql statement
$sql = "TRUNCATE marketplace;"; // Clears down the current marketPlace table ready for new INSERTS
//Loop through each multicall
foreach ($outputj['multiCall'] as $orderBook) {
foreach ($orderBook['marketplace'] as $orderLine) {
$type = $orderLine['type'];
$price = $orderLine['amountCurrency'];
// Add new SQL record (This ignores any duplicate values)
$sql .="INSERT IGNORE INTO marketplace (type, price) VALUES ('" . $type . "'," . $price . ");";
}
$marketplaceCounter++;
}
// Now run all the SQL's to update database table
if (strlen($sql) > 0) {
if (Database::$conn->multi_query($sql) === TRUE) {
echo mysqli_error(Database::$conn);
//echo "New records created successfully";
} else {
echo mysqli_error(Database::$conn);
echo "Error: " . $sql . "<br>" . Database::$conn->error;
}
}
echo date('Y-m-d H:i:s',time()) . " == Marketplace Orderbook retreived == <BR><BR>" . PHP_EOL;
} else {
echo date('Y-m-d H:i:s',time()) . " Failed to get Marketplace data. Output was: " . $marketData . "<BR>" . PHP_EOL;
die();
}
}
我已经追了几个小时,我真的不明白为什么在调用 sleep(1)
函数后添加 processMarketplace()
延迟会有帮助。我还尝试将 1.php 和 2.php 合并为一个脚本,这会产生相同的结果。 2.php 只是执行 SELECT * FROM marketPlace
查询,除非我有 sleep(1)
,否则返回 NULL。
我是否遗漏了一些简单的东西,还是我真的很糟糕?
我应该补充一点,我正在使用 InnoDB 表。
在 1.php 中是这样调用的:
$marketData = getData($user,$api); // Get Marketplace Data
processMarketplace($marketData); // Process marketplace data
sleep(1); // Bizzare sleep needed for the select statement that follows in 2.php to return non-null
include "2.php"; // Include 2nd script to do some select statements on marketPlace table
2.php 包含以下调用:
$typeArray = array('1','2','3');
foreach ($typeArray as $type) {
initialPopulate($type);
}
function initialPopulate($type) {
// Reset supplementary prices
mysqli_query(Database::$conn, "UPDATE marketPlace SET price_curr = '999999' WHERE type='" . $type . "'");
echo mysqli_error(Database::$conn);
// Get marketplace data <--- This is the one that is strangely returning Null (after the first loop) unless I place the sleep(1) before including 1.php
$query = "SELECT * FROM marketPlace WHERE type='" . $type . "'";
$result = mysqli_query(Database::$conn, $query);echo mysqli_error(Database::$conn);
$resultNumRows = mysqli_num_rows($result);echo mysqli_error(Database::$conn);
// Create array from mysql data
$rows = array();
while($r = mysqli_fetch_assoc($result)) {
$rows[] = $r;
}
// Get information from the offertypes table
$query2 = "SELECT offerID FROM queryTypes WHERE type='" . $type . "'";
$result2 = mysqli_query(Database::$conn, $query2);echo mysqli_error(Database::$conn);
// Create array from mysql data
$rows2 = array();
while($r2 = mysqli_fetch_row($result2)) {
$rows2[] = $r2;
}
// Loop through marketplace data and apply data from the offertypes table
$sql1 = ""; // Create a blank SQL array that we will use to update the database
$i = 0;
foreach ($rows as $row) {
$sql1 .= "UPDATE marketPlace SET enrichmentType = " . $rows2[$i][0] . " WHERE type='" . $type . "';";
$i++;
}
// Now run all the SQL's to update database table
if (strlen($sql1) > 0) {
if (Database::$conn->multi_query($sql1) === TRUE) {
echo mysqli_error(Database::$conn);
//echo "New records created successfully";
} else {
echo mysqli_error(Database::$conn);
echo "Error: " . $sql1 . "<br>" . Database::$conn->error;
}
}
}
答案 0 :(得分:1)
您正在使用 mysqli:multi_query
。
与 query
不同,multi_query 不会立即检索结果。检索结果必须使用 mysqli::use_result
文档中的示例:
/* execute multi query */
if ($mysqli->multi_query($query)) {
do {
/* store first result set */
if ($result = $mysqli->use_result()) {
while ($row = $result->fetch_row()) {
printf("%s\n", $row[0]);
}
$result->close();
}
/* print divider */
if ($mysqli->more_results()) {
printf("-----------------\n");
}
} while ($mysqli->next_result());
}
您不需要打印结果,但如果您不检索它们,则不能保证 INSERT 已完成。
在 use_result
的文档中注意
https://www.php.net/manual/en/mysqli.use-result.php
说明
<块引用>"必须调用此函数或 mysqli_store_result() 函数 在可以检索查询结果之前,以及其中一个 必须调用以阻止对该数据库连接的下一个查询 失败。”
由于未调用 store_result 或 use_result,您将获得不可预测的结果。