PHP PDO MYSQL — Самый простой способ сравнить массив с запросом и вернуть массив с результатами не в результате запроса?

В PHP у меня есть простой массив под названием $allFiles лайк:

Array
(
[0] => test1.csv
[1] => test2.csv
[2] => test3.csv
)

В MySQL у меня есть таблица, которая имеет такие значения, как:

| ID | PROCESSED |
| 0  | test2.csv |

Какой самый простой способ (используя PDO в качестве метода подключения) для сравнения $allFiles в таблицу и вернуть новый массив $newFiles который содержит:

Array
(
[0] => test1.csv
[1] => test3.csv
)

(это файлы, которые не представлены в таблице в MySQL)

Я ознакомился с руководством, но, похоже, не могу найти ничего, что бы относилось именно к этому, хотя я мог что-то упустить. Любой вклад будет принята с благодарностью, спасибо!

1

Решение

Для этого нет готовой функции. В большинстве случаев вы обнаружите, что не существует готового решения вашей проблемы. Вы должны будете написать код самостоятельно, что не так уж сложно: запросите в БД все имена файлов, создайте массив с результатами, затем получите разницу между вашим массивом и результатами запроса.
Основным примером будет:

$stmt = $pdo->prepare('SELECT PROCESSED FROM db.table WHERE PROCESSED IN (?,?,?)');
$stmt->execute($allFiles);
$existing = array();
while($row = $stmt->fetch(PDO::FETCH_OBJ))
$existing[] = $row->PROCESSED;//construct array containing existing values
$notFound = array_diff($allFiles, $existing);
var_dump($notFound);

Вы можете сделать запрос немного более динамичным, используя длину $allFiles массив и добавить ? соответственно заполнители:

$allFiles = array_filter(array_unique($allFiles));//clean array
$placeholders = array_fill(0, count($allFiles), '?');
$stmt = $pdo->prepare(
'SELECT PROCESSED FROM db.table WHERE PROCESSED IN ('.implode(',', $placeholders).')'
);
//alternative:
$stmt = $pdo->prepare(
'SELECT PROCESSED FROM db.table WHERE PROCESSED IN ('.
substr(
str_repeat('?,',count($allFiles)),//repeat ?, as many times as there are values
0,-1//remove trailing ",").')'
);
$stmt->execute(array_values($allFiles));//better safe than sorry
//rest is the same as before

Это позволяет обрабатывать массив любой длины.

2

Другие решения

PDO возвращает массив значений из вашей таблицы. Вы можете проверить, есть ли ваши результаты в массиве БД. Вы можете проверить ключ массива, если ваши результаты уже находятся в массиве PDO, пропустите этот результат. Если ваш результат отсутствует в массиве PDO, создайте новый массив с этим значением или значениями.

Примечание: PDO возвращает числовой и текстовый ключ для одной записи. Когда вы проверяете, существует ли ключ, вы должны проверить, является ли ваш ключ цифровым ключом. Если числовой, пропустите тот.

2

Как сказали ребята в комментариях, нет функции PDO, которая бы делала это прямо. Сначала вам нужно собрать свои результаты, поместить их в массив и использовать array_diff(),

Грубый пример:

$allFiles = ['test1.csv', 'test2.csv', 'test3.csv'];

$con = new PDO('mysql:host=localhost;dbname=DATABASE', 'username', 'password');
$query = $con->query('SELECT PROCESSED FROM table_name');
$db_results = [];
while($row = $query->fetch(PDO::FETCH_ASSOC)) {
$db_results[] = $row['PROCESSED'];
}

$results = array_diff($allFiles, $db_results);
2