【问题标题】:PHP Regular Expressions and CSV ValidationPHP 正则表达式和 CSV 验证
【发布时间】:2015-07-05 21:17:09
【问题描述】:

我正在尝试创建一个 CSV 检查器,它将检查的数据插入到数据库中,并将任何不成功的数据添加到 .txt 文件中。 我正在尝试使用正则表达式来验证我插入的数据,没有任何验证的 while 循环可以正常工作并且插入正常,但是一旦使用正则表达式它就不起作用。

<?php
    include_once('connection.php');
    error_reporting(E_ALL);
    date_default_timezone_set('Europe/London');
    $date = date('d/m/y h:i:s a', time());
    $filetxt = "./errors.txt";
    $errors = array();
    $var1 = 5;
    $var2 = 1000;
    $var3 = 10;
    $sql = '';

    if(isset($_POST["Import"]))
    {
        echo $filename=$_FILES["file"]["tmp_name"]; 
        if($_FILES["file"]["size"] > 0)
        {
            $file = fopen($filename, "r");
            while(($emapData = fgetcsv($file, 10000, ",")) !==FALSE)
            {
                if(isset($_GET['strProductCode']))
                {
                    $emapData[0] =  $conn->real_escape_string(trim($_POST['strProductCode']));

                    if (!preg_match("^[a-zA-Z0-9]+$^", $_POST['strProductCode']))
                    {
                        $errors['strProductCode'];
                    }
                }
                if(isset($_GET['strProductName']))
                {
                    $emapData[1] =  $conn->real_escape_string(trim($_GET['strProductName']));
                    if (!preg_match("^[a-zA-Z0-9]+$^", $_POST['strProductName']))
                    {
                        $errors['strProductName'];
                    }
                }
                if(isset($_GET['strProductDesc']))
                {
                    $emapData[2] =  $conn->real_escape_string(trim($_GET['strProductDesc']));
                    if (!preg_match("^[a-zA-Z0-9]+$^", $_POST['strProductDesc']))
                    {
                        $errors['strProductDesc'];
                    }
                }
                if(isset($_GET['intStock']))
                {           
                    if (!preg_match("^[0-9]", $_POST['intStock']))
                    {
                        $errors['intStock'];
                    }
                }
                if(isset($_GET['intPrice']))
                {
                    if (!preg_match("[0-9]", $_POST['intPrice']))
                    {
                        $errors['intPrice'];
                    }
                }
                if(isset($_GET['dtmDiscontinued'])){
                    if($emapData[6] == preg_match("[a-zA-Z]", $_POST['dtmDiscontinued']))
                    {

                        $emapData[6] = $date;
                        echo $date;
                    }else{
                            $emapData[6] = Null;
                        }
                }
                if(count($errors > 0))
                {
                    // errors 
                    $write = "$emapData[0], $emapData[1], $emapData[2], $emapData[3], $emapData[4], $emapData[5], $emapData[6]\r\n";     
                    file_put_contents($filetxt , $write , FILE_APPEND);

                }else{
                    // insert into Database
                        $sql = "INSERT INTO tblproductdata(strProductCode, strProductName, strProductDesc, intStock, intPrice, dtmAdded, dtmDiscontinued) VALUES('$emapData[0]','$emapData[1]','$emapData[2]','$emapData[3]','$emapData[4]','$date','$emapData[6]')";
                    $res=$conn->query($sql);
                    }

            }
            fclose($file);
            echo "CSV File has successfully been Imported";
            echo "<br>";
            echo "Any errors within the CVS Database are reported here.";
            echo "<br>";
            $fh = fopen($filetxt, 'r');
            $theData = fread($fh, filesize($filetxt));
            fclose($fh);
            echo $theData;

        }else{
            echo "Invalid File: Please Upload a Valid CSV File";    
        }
            header("Location: index.php");
    }
?>

我对 PHP 的了解并不多,但这是我最好的尝试。 任何帮助将不胜感激。

【问题讨论】:

  • 请更详细地定义“不起作用”。乍一看,我发现您经常取消引用 $errors 数组中的值,但不要使用这些值(如 $errors['intPrice'];)。这些语句是否可能意味着赋值(如 $errors['intPrice'] = TRUE; )?
  • 好吧,我所说的“不起作用”是代码不执行任何if(isset($_GET['xxxxxxx'])),而if(isset($_GET['xxxxxxx'])) 又不会向数据库添加任何数据,只会推送由while 处理的任何数据循环进入 .txt 文件,该文件用于存储 CSV 文件中不符合验证要求的行。

标签: php mysql regex csv


【解决方案1】:

您的代码中有几个问题。让我们从正则表达式和错误检查开始:

  1. 您的某些表达方式无效。请注意,每个表达式的开头和结尾都需要一个分隔符。在您的某些表达式(如^[0-9])中,这些分隔符丢失了。另请注意,使用^ 作为正则表达式的分隔符并不是一个好的选择,因为^ 字符在正则表达式中也有特殊含义。

    这实际上应该导致 PHP 警告。我看到你启用了error_reporting;您还应该查看您的 display_errors 设置。

  2. 正如我在评论中提到的,您没有为 $errors 数组分配任何值。语句$errors['strProductName'] 本身不会改变数组;这意味着$errors 将始终为空。您可能的意思是:

    $errors['strProductName'] = TRUE;
    
  3. 您实际上是在检查count($errors &gt; 0),而您应该检查count($errors &gt; 0)count($errors &gt; 0) 转换为 count(TRUE)count(FALSE) 两者都等于 1。

其他一些注意事项:

  1. 有时,您检查$_GET['strProductCode'],然后使用$_POST['strProductCode']
  2. 您不会为每次迭代重置$errors 数组。这意味着对于您阅读的每一行,$errors 变量仍将包含上一次迭代的错误。因此,第一个无效行也会导致后面的所有行也被识别为无效。
  3. 当其中一个参数的格式无效时,您会注册一个错误,但当其中一个参数根本没有设置时(即当isset($_POST[...])FALSE 时)。他们每个人都应该是某事。像这样:

    if (isset($_POST['strProductCode'])) {
        $emapData[0] = $conn->real_escape_string(trim($_POST['strProductCode']));
        if (!preg_match("^[a-zA-Z0-9]+$^", $_POST['strProductCode'])) {
            $errors['strProductCode'] = TRUE;
        }
    } else {
        $errors['strProductCode'] = TRUE;
    }
    

【讨论】:

  • 好的,那么哪个是更好的分隔符选择? / 会是一个更好且可以接受的吗?我已经修改了 2 和 5 的代码。它们是直截了当的。至于4.是$_GET还是$_POST的情况?还是整个if(isset($_GET['strProductCode'])) 的声明无效?
  • 可以使用任意字符作为分隔符;但是,如果您在表达式中使用该字符,则必须对其进行转义。 / 似乎在大多数文档中都使用过,通常是一个不错的选择。关于$_GET$_POST:这取决于您的表单提交方式。如果使用 POST 请求提交,则使用$_POST,否则使用$_GET
  • 好的,我已经接受了你所说的,现在它没有出现任何错误,但是代码仍然没有执行,除非我将 if(isset($_POST['strProductCode'])) 更改为 if(!isset($_POST['strProductCode'])) 然后我收到错误消息“未定义的索引:第 31 行 C:\wamp\www\x-import\index.php 中的 strProductCode”等。strProductCode 和其他列是否应该在顶部预定义?
  • 是的,这可能是因为您仅在参数设置且格式无效时触发错误,而不是在参数根本未设置时触发错误。我已经相应地更新了我的答案以解决这一点。
猜你喜欢
  • 2012-03-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多