Если писать свою обертку для работы с mysql, то mysqli.
Во всех остальных случаях - PDO.
Для ответа на вопрос надо понимать только одну вещь: функции mysqli API - низкоуровневые, и не предназначены для использования их напрямую. Обеспечивая большую гибкость, они в то же время требуют очень многословного кода, что неприемлемо в коде приложения.
PDO же, в свою очередь, это такая недообертка, которая позволяет сократить количество кода до приемлемого уровня.
В любом случае надо помнить, что единственная причина использовать тот и другой драйвер - это подстановка переменных в запрос
только через плейсхолдеры.
В простых случаях разница не столь заметна, 5 строк против трех:
$stmt = $mysqli->prepare("SELECT * FROM articles WHERE date=?");
$stmt->bind_param("s", $date);
$stmt->execute();
$res = $stmt->get_result();
$news = $stmt->fetch_all();
/* vs. */
$stmt = $pdo->prepare("SELECT * FROM articles WHERE date=?");
$stmt->execute([$date]);
$news = $stmt->fetchAll();
Но в более сложных код mysqli растет как на дрожжах, в то время как у PDO... остается столько же!
$stmt = $mysqli->prepare("SELECT id, name FROM categories WHERE section=?");
$stmt->bind_param("s", $sec);
$stmt->execute();
$res = $stmt->get_result();
$cats = array();
while($row = $res->fetch_assoc())
{
$cats[$row['id']] = $row['name'];
}
/* vs. */
$stmt = $pdo->prepare("SELECT id, name FROM categories WHERE section=?");
$stmt->execute([$sec]);
$cats = $stmt->fetchAll(PDO::FETCH_PAIRS);
Правда, всем им далеко до нормальных врапперов
$cats = $db->getIndCol("id","SELECT id, name FROM categories WHERE section=?s", $sec);