php& PDO:占位符导致错误的负载数据流动

发布于 2025-01-30 16:29:08 字数 1930 浏览 2 评论 0原文

我在悖论中度过了最后几个小时。我使用此查询将CSV文件导入数据库。

$query = $this->pdo->prepare('

    LOAD DATA LOCAL INFILE
        :file
    INTO TABLE
        product_feeds_raw
    FIELDS TERMINATED BY
        :fields_terminated_by
    OPTIONALLY ENCLOSED BY
        :fields_optionally_enclosed_by
    LINES TERMINATED BY
        :lines_terminated_by
    IGNORE 1 LINES
    (
        `aaa`, 
        `bbb`
    )
    SET
        task_id = :task_id
');

$params = [

    'file' => $this->path_to_file,
    'fields_terminated_by' => $fields_terminated_by,
    'fields_optionally_enclosed_by' => $fields_optionally_enclosed_by,
    'lines_terminated_by' => $lines_terminated_by,
    'task_id' => $this->task_id
];

$query->execute($params);

整个文件及其设置(分离器,外壳,线终止等)来自最终用户的基于OAUTH的API。我告诉您这显然我不能相信用户输入,因此我必须使用占位符。

问题在于,PDO逃脱了此类参数的方式是奇怪的。这是用户通过API发送的内容:

'fields_terminated_by' => ';',
'fields_optionally_enclosed_by' => '"',
'lines_terminated_by' => '\n',

本质上,我们具有 \ n,这对于CSV很常见。我使用这些变量为我的占位符喂食,但PDO将它们转化为以下混乱:

LOAD DATA LOCAL INFILE
    '../../myfile.csv'
INTO TABLE
    product_feeds_raw
FIELDS TERMINATED BY
    ';'
OPTIONALLY ENCLOSED BY
    '\"' <-------------- WRONG
LINES TERMINATED BY
    '\\n' <-------------- WRONG
IGNORE 1 LINES

您可以看到PDO在我的前面添加了不必要的\” 。对于\ n,变成\\ n也是如此。结果,MySQL无法导入CSV,因为分界符是不同的。查询应该就是这样:

LOAD DATA LOCAL INFILE
    '../../myfile.csv'
INTO TABLE
    product_feeds_raw
FIELDS TERMINATED BY
    ';'
OPTIONALLY ENCLOSED BY
    '"' <-------------- CORRECT
LINES TERMINATED BY
    '\n' <-------------- CORRECT
IGNORE 1 LINES

我花了几个小时查看其他脚本,但是似乎没有人使用加载数据填充的占位符。不适合定界数。

我知道我可以简单地摆脱占位符的占位符,而只是在查询中使用变量,但我不喜欢这种方法。此外,我应该依靠定制的逃生来消毒用户输入。

建议?

I spent the last few hours in a paradox. I use this query to import a CSV file into my database.

$query = $this->pdo->prepare('

    LOAD DATA LOCAL INFILE
        :file
    INTO TABLE
        product_feeds_raw
    FIELDS TERMINATED BY
        :fields_terminated_by
    OPTIONALLY ENCLOSED BY
        :fields_optionally_enclosed_by
    LINES TERMINATED BY
        :lines_terminated_by
    IGNORE 1 LINES
    (
        `aaa`, 
        `bbb`
    )
    SET
        task_id = :task_id
');

$params = [

    'file' => $this->path_to_file,
    'fields_terminated_by' => $fields_terminated_by,
    'fields_optionally_enclosed_by' => $fields_optionally_enclosed_by,
    'lines_terminated_by' => $lines_terminated_by,
    'task_id' => $this->task_id
];

$query->execute($params);

The entire file with its settings (separator, enclosure, line termination etc.) arrives from an OAuth-based API from end-users. I am telling you this to underline that obviously I cannot trust user input hence I must use placeholders.

The problem is that the way PDO escapes such parameters is odd. This is what the user sends via API:

'fields_terminated_by' => ';',
'fields_optionally_enclosed_by' => '"',
'lines_terminated_by' => '\n',

In essence we have ; " and \n which is pretty common for a CSV. I use these variables to feed my placeholders but PDO transforms them into this mess:

LOAD DATA LOCAL INFILE
    '../../myfile.csv'
INTO TABLE
    product_feeds_raw
FIELDS TERMINATED BY
    ';'
OPTIONALLY ENCLOSED BY
    '\"' <-------------- WRONG
LINES TERMINATED BY
    '\\n' <-------------- WRONG
IGNORE 1 LINES

As you can see PDO adds an unnecessary \ in front of my ". Same goes for \n that becomes \\n. As result mysql fails to import the CSV because delimiters are different. The query should have been this:

LOAD DATA LOCAL INFILE
    '../../myfile.csv'
INTO TABLE
    product_feeds_raw
FIELDS TERMINATED BY
    ';'
OPTIONALLY ENCLOSED BY
    '"' <-------------- CORRECT
LINES TERMINATED BY
    '\n' <-------------- CORRECT
IGNORE 1 LINES

I spent hours looking at other scripts but no one seems to use placeholders with LOAD DATA INFILE. Not for delimeters.

I know I could simply get rid of placeholders for delimiters and just use variables inside the query but I don't like this approach. Moreover I should rely on custom-made escapings to sanitize user-input.

Suggestions?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文