У меня были похожие проблемы, и для небольших файлов вышеупомянутое решение Johannes Schaub работало как прелесть для меня.
Однако для файлов, которые немного больше, он столкнулся с проблемами с массивом символов предел компилятора. Поэтому я написал небольшое приложение кодировщика, которое преобразует содержимое файла в массив двумерных символов с одинаковыми размерами (и, возможно, нулями заполнения). Он создает выходные текстовые файлы с данными 2D-массива, такими как:
const char main_js_file_data[8][4]= {
{'\x69','\x73','\x20','\0'},
{'\x69','\x73','\x20','\0'},
{'\x61','\x20','\x74','\0'},
{'\x65','\x73','\x74','\0'},
{'\x20','\x66','\x6f','\0'},
{'\x72','\x20','\x79','\0'},
{'\x6f','\x75','\xd','\0'},
{'\xa','\0','\0','\0'}};
, где 4 фактически является переменной MAX_CHARS_PER_ARRAY в кодере. Затем файл с результирующим C-кодом, называемым, например, «main_js_file_data.h», может легко быть встроен в приложение C ++, например, следующим образом:
#include "main_js_file_data.h"
Вот исходный код кодировщика :
#include <fstream>
#include <iterator>
#include <vector>
#include <algorithm>
#define MAX_CHARS_PER_ARRAY 2048
int main(int argc, char * argv[])
{
// three parameters: input filename, output filename, variable name
if (argc < 4)
{
return 1;
}
// buffer data, packaged into chunks
std::vector<char> bufferedData;
// open input file, in binary mode
{
std::ifstream fStr(argv[1], std::ios::binary);
if (!fStr.is_open())
{
return 1;
}
bufferedData.assign(std::istreambuf_iterator<char>(fStr),
std::istreambuf_iterator<char>() );
}
// write output text file, containing a variable declaration,
// which will be a fixed-size two-dimensional plain array
{
std::ofstream fStr(argv[2]);
if (!fStr.is_open())
{
return 1;
}
const std::size_t numChunks = std::size_t(std::ceil(double(bufferedData.size()) / (MAX_CHARS_PER_ARRAY - 1)));
fStr << "const char " << argv[3] << "[" << numChunks << "]" <<
"[" << MAX_CHARS_PER_ARRAY << "]= {" << std::endl;
std::size_t count = 0;
fStr << std::hex;
while (count < bufferedData.size())
{
std::size_t n = 0;
fStr << "{";
for (; n < MAX_CHARS_PER_ARRAY - 1 && count < bufferedData.size(); ++n)
{
fStr << "'\\x" << int(unsigned char(bufferedData[count++])) << "',";
}
// fill missing part to reach fixed chunk size with zero entries
for (std::size_t j = 0; j < (MAX_CHARS_PER_ARRAY - 1) - n; ++j)
{
fStr << "'\\0',";
}
fStr << "'\\0'}";
if (count < bufferedData.size())
{
fStr << ",\n";
}
}
fStr << "};\n";
}
return 0;
}
Возможно с помощью mysqli_multi_query () .
Пример:
<?php
$mysqli = new mysqli($host, $user, $password, $database);
// create string of queries separated by ;
$query = "INSERT INTO images (project_id, user_id, image_name, date_created, link_to_file, link_to_thumbnail, given_name) VALUES ('$project_id', '$user_id', '$image_name', '$date_created', '$link_to_file', '$thumbnail', '$ImageName');";
$query .= "INSERT INTO images_history (project_id, user_id, image_name, date_created, link_to_file, link_to_thumbnail, given_name, day, month, year) VALUES ('$project_id', '$user_id', '$image_name', '$date_created', '$link_to_file', '$thumbnail', '$ImageName', '$day', '$month', '$year');";
// execute query - $result is false if the first query failed
$result = mysqli_multi_query($mysqli, $query);
if ($result) {
do {
// grab the result of the next query
if (($result = mysqli_store_result($mysqli)) === false && mysqli_error($mysqli) != '') {
echo "Query failed: " . mysqli_error($mysqli);
}
} while (mysqli_more_results($mysqli) && mysqli_next_result($mysqli)); // while there are more results
} else {
echo "First query failed..." . mysqli_error($mysqli);
}
Ключ в том, что вы должны используйте mysqli_multi_query
, если вы хотите выполнить несколько запросов в одном вызове. По соображениям безопасности mysqli_query
не будет выполнять несколько запросов, чтобы предотвратить инъекции SQL.
Также помните о поведении mysqli_store_result
. Он возвращает FALSE
, если запрос не имеет набора результатов (какие INSERT
запросы не выполняются), поэтому вы также должны проверить mysqli_error
, чтобы увидеть, что он возвращает пустую строку, означающую, что INSERT
был успешным.
См. mysqli_multi_query mysqli_more_results mysqli_next_result mysqli_store_result
Раз и навсегда! Используйте эту функцию для получения результатов по неограниченному количеству запросов в любом месте вашего скрипта.
blockquote>Функция:
Вы просто передаете результат мультипроцесса функции, и это возвращает все результаты и ошибки, обнаруженные в каждом запросе.
function loop_multi($result){ //use the global variable $conn in this function global $conn; //an array to store results and return at the end $returned = array("result"=>array(),"error"=>array()); //if first query doesn't return errors if ($result){ //store results of first query in the $returned array $returned["result"][0] = mysqli_store_result($conn); //set a variable to loop and assign following results to the $returned array properly $count = 0; // start doing and keep trying until the while condition below is not met do { //increase the loop count by one $count++; //go to the next result mysqli_next_result($conn); //get mysqli stored result for this query $result = mysqli_store_result($conn); //if this query in the loop doesn't return errors if($result){ //store results of this query in the $returned array $returned["result"][$count] = $result; //if this query in the loop returns errors }else{ //store errors of this query in the $returned array $returned["error"][$count] = mysqli_error($conn); } } // stop if this is false while (mysqli_more_results($conn)); }else{ //if first query returns errors $returned["error"][0] = mysqli_error($conn); } //return the $returned array return $returned; }
Использование:
$query = "INSERT INTO table1 (attribute1) VALUES ('value1');"; $query .= "INSERT INTO table2 (attribute2) VALUES ('value2');"; $query .= "SELECT * FROM table3;"; //execute query $result = mysqli_multi_query($conn, $query); //pass $result to the loop_multi function $output = loop_multi($result);
Выход
$ включает в себя 2 массива «результат» и «результат», ошибка ", упорядоченная по запросу. Например, если вам нужно проверить, произошли ли какие-либо ошибки при выполнении третьего запроса и получить его результат, вы можете сделать:
if(isset($output['error'][2]) && $output['error'][2] !== ""){ echo $output['error'][2]; }else{ while($row = $output['result'][2]->fetch_assoc()) { print_r($row); } }