如何从' ^'中获取产品ID分开列表?

时间:2018-04-26 16:34:56

标签: php regex

我有一个' ^'分隔产品ID号列表,我需要获取产品ID号,然后用它来查询SQL数据库。产品ID号存储在$ _SESSION哈希中。例如:

SKUS: jpn18726^gr172645^123746^17246^eu186726^...

我能想到的代码是这样的:

$prodmat = $_SESSION["product"];
if(preg_match("(\d+)(^\s*\d+)*", $prodmat) {
    $stmt = "select shipcode from materials where material='???'";
}

基本上,我想从' ^'中提取产品ID号。分隔列表,然后使用产品ID号查询数据库。

2 个答案:

答案 0 :(得分:6)

做一些爆炸:

$prod_list = 'SKUS: jpn18726^gr172645^123746^17246^eu186726';
$list_parts = explode(':', $prod_list); // separate the text
$prods = explode('^', trim($list_parts[1])); // trim and put the list in an array
print_r($prods);

结果:

Array
(
    [0] => jpn18726
    [1] => gr172645
    [2] => 123746
    [3] => 17246
    [4] => eu186726
)

现在,您可以使用查询遍历数组。

foreach($prods as $product) {
     $sql = "SELECT foo, bar, WHERE products WHERE id = ?";
     // bind the current product
     // do the query
}

答案 1 :(得分:1)

如果可能,您应该只执行一个查询。如果你使用mysqli,你可以使用下面的代码块,虽然我会推荐pdo,因为在处理可变数量的占位符时它更容易。

此代码无法验证输入数据。它假定您的SESSION数据100%可靠且格式可靠。如果您需要验证,那么您将需要正则表达式进行验证。 ......如果你的id只包含数字和字母,可能类似于~^SKUS: [a-z\d]+(?:\^[a-z\d]+)*$~

代码:

if (!empty($_SESSION["product"])) {
    // $_SESSION["product"] = 'SKUS: jpn18726^gr172645^123746^17246^eu186726';
    // "SKUS: " is fixed/constant, so just remove it by known substring position/length

    $params = explode('^', substr($_SESSION["product"],6));  // trim off leading substring BEFORE exploding

    $count = count($params);
    $csph = implode(',', array_fill(0, $count, '?'));  // comma-separated placeholders

    if(!$stmt = $conn->prepare("SELECT `shipcode` FROM `materials` WHERE `material` IN ($csph);")){
        echo "Syntax Error @ prepare: " , $conn->error;  // do not echo error on public site
    }else{
        array_unshift($params, str_repeat('s', $count));  // prepend the type values string
        $ref = [];  // add references
        foreach ($params as $i => $v) {
            $ref[$i] = &$params[$i];  // pass by reference as required/advised by the manual
        }
        call_user_func_array([$stmt, 'bind_param'], $ref);    

        if (!$stmt->execute()) {
            echo "Error @ bind_param/execute: " , $stmt->error;  // do not echo error on public site
        } elseif (!$stmt->bind_result($shipcode)) {
            echo "Error @ bind_result: " , $stmt->error;  // do not echo error on public site
        } else {
            while ($stmt->fetch()) {
                // do something with $shipcode
            }
            $stmt->close();
        }
    }
} else {
    echo "Missing/Invalid product data";
}

如果您需要使用相应的ID识别您的代码,请将material列添加到SELECT子句和bind_result()来电。

所有这一切,如果您可以放心地验证/清理您的SESSION数据,您可以避免对预先准备好的声明进行卷积,只需在SELECT中使用IN进行WHERE查询{1}}子句如:WHERE materials IN (' . implode("','", $params) . ')