Как выполнить sh команду в скрипте php с меняющейся составляющей

Есть команда sh следующего вида:

mysql -B -u user -p'password' database \
    -h host \
    -e "SELECT column1, column2 FROM table WHERE blablabla LIMIT $x" \
    | sed "s/\"/\"\"/g;s/'/\'/;s/\t/;/g" \
    > text.csv

При этом переменная $x содержит результат sql-запроса и меняется в зависимости от данных базы, поэтому sh скрипт с другого файла отдельно запускать через shell_exec не вариант, наверное.

Пришел к тому, что нужно сделать два запроса вида:

// 1.
$x = mysqli_query("SELECT COUNT blablabla"); // сохраняет число, которое нужно передавать в запрос sh
// 2.
$result = shell_exec("mysql -B -u user -p'password' database -h host -e 'SELECT column1, column2 FROM table WHERE blablabla LIMIT $x'  | sed 's/\"/\"\"/g;s/'/\'/;s/\t/;/g' > text.csv");

Возникла проблема с кавычками и тянет на говнокод

Если есть эксперты баша, саши и т.п., был бы рад посоветоваться:)


Ответы (1 шт):

Автор решения: Maxim Timakov

Для выполнения запросов ненужно использовать shell: PHP может и сам общаться с базой данных.

Для подключения к БД и выполнения запросов можно задействовать модуль PDO

Подключение к MySQL/MariaDB:

<?php

$config = <<<CFG
{
    "dsn": "mysql:dbname=tests;host=localhost",
    "user": "tests",
    "password": "pass"
}
CFG;

$pdo_cfg = json_decode($config);
$pdo_opt = [
    \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION
];

$db = new \PDO(
    $pdo_cfg->dsn, $pdo_cfg->user, $pdo_cfg->password, $pdo_opt
);

Получить количество:

$sql_get_count = <<<SQL_GET_COUNT

select count(*) as cnt
    from `test_tbl`;
SQL_GET_COUNT;

$query = $db->prepare($sql_get_count);
$query->execute();

$count = $query->fetch(\PDO::FETCH_ASSOC)['cnt'];

var_dump($count);

Запросить данные:

$sql_get_data = <<<SQL_GET_DATA
select * from `test_tbl`
    where
        some_id = :some_id
    limit
        :row_limit
;
SQL_GET_DATA;

$query = $db->prepare($sql_get_data);
$query->bindValue(':some_id', 42, \PDO::PARAM_INT);
$query->bindValue(':row_limit', $count, \PDO::PARAM_INT);
$query->execute();

А для записи результата в CSV функцию fputcsv

// open file
$csv_file = fopen("text.csv", "w");

// save query results
while ($row = $query->fetch(\PDO::FETCH_NUM)) {
    fputcsv($csv_file, $row, ';');
}
fclose($csv_file);
→ Ссылка