1

ひどい見出しでごめんなさい、以下に説明しようと思います。

trueまたはfalseを返す小さな関数をたくさん作成しました。

validateName()
validateEmail()
validateAddr()
validateBirtd()
validateUsername()

現在、CSVファイルでインポートされた多くのデータをループして、どのデータが有効かどうかをチェックインしています(trueまたはfalseを返します)。

私はそれをこのようにします:

if (validateName($data[0]) == true AND validateEmail($data[1]) == true AND validateAddr($data[3]) == true AND validateBirtd($data[5]) == true AND validateUsername($data[6])==true) {
 // create array to import etc etc
}else{
 // create other array with data who failed validation, to show user later..etc etc
}

私の質問は-これを行うためのより賢い方法はありますか?失敗した検証ごとにリストを作成することは可能でしょうか?3つのエントリがvalidateEmail()関数に失敗し、10のエントリがvalidateEmailとvalidateName()の両方に失敗したとします。

これを並べ替えて、「これらのエントリは電子メールの検証に失敗しました」と「これらのエントリは名前と電子メールの検証に失敗しました」とユーザーに伝える方法はありますか。

一度に1つのフィールドを検証することを考えましたが、この方法では、1つのエントリに複数の検証エラーがある場合に重複が発生します。

どこでこれができるのかわからないようなロジックがあったら、かっこいいでしょう

4

3 に答える 3

5

関数を作成できます。

function validate($data) {
  $errors = array();
  $fields = array('Name', 'Email', 'Addr', 'Birtd', 'UserName');
  foreach ($fields as $i => $field) {
    $func = 'validate'.$field;
    if (!$func($data[$i])) {
      $errors[] = $field;
    }
  }
  return $errors;
}

$errors = validate($data);
if (empty($errors)) {
  // create array to import etc etc
} else {
  // errors
  echo 'There are errors with ' . implode(',', $errors);
}
于 2012-11-26T02:30:27.330 に答える
2

を使用Iteratorsして、CSVコンテンツの取得とフィルタリングを同時に行うことができます。各CSVインデックスに異なるコールバックを追加することもできます

$csv = new CSVFilter(new CSVIterator("log.txt"));
$csv->addFilter(0, "validateName"); //<------------ Means validate Index at 0
$csv->addFilter(1, "validateEmail");
$csv->addFilter(2, "validateAddr");
$csv->addFilter(3, "validateBirtd");
$csv->addFilter(4, "validateName");
$csv->addFilter(5, "validateUsername");

foreach ( $csv as $data ) {
    var_dump($data);
}

//To get Errors 
var_dump($csv->getErrors());

CSVフィルター

class CSVFilter extends FilterIterator {
    protected $filter = array();
    protected $errors = array();

    public function __construct(Iterator $iterator) {
        parent::__construct($iterator);
    }

    public function addFilter($index, Callable $callable) {
        $this->filter[$index] = $callable;
        $this->errors[$callable] = 0;
    }

    public function getErrors() {
        return $this->errors;
    }

    public function accept() {
        $line = $this->getInnerIterator()->current();
        $x = true;
        foreach ($this->filter  as $key => $var ) {
            if (isset($line[$key])) {
                $func = $this->filter[$key];
                $func($var) or $this->errors[$func] ++ and $x = false;
            }
        }
        return $x;
    }
}

CSVIterator

class CSVIterator implements \Iterator {
    protected $fileHandle;
    protected $line;
    protected $i;

    public function __construct($fileName) {
        if (! $this->fileHandle = fopen($fileName, 'r')) {
            throw new \RuntimeException('Couldn\'t open file "' . $fileName . '"');
        }
    }

    public function rewind() {
        fseek($this->fileHandle, 0);
        $this->line = fgetcsv($this->fileHandle);
        $this->i = 0;
    }

    public function valid() {
        return false !== $this->line;
    }

    public function current() {
        return array_map("trim", $this->line);
    }

    public function key() {
        return $this->i;
    }

    public function next() {
        if (false !== $this->line) {
            $this->line = fgetcsv($this->fileHandle);
            $this->i ++;
        }
    }

    public function __destruct() {
        fclose($this->fileHandle);
    }
}

単純なランダム関数

function validateName($var) {
    return mt_rand(0, 5);
}

function validateEmail($var) {
    return mt_rand(0, 5);
}

function validateAddr($var) {
    return mt_rand(0, 5);
}

function validateBirtd($var) {
    return mt_rand(0, 5);
}

function validateUsername($var) {
    return mt_rand(0, 5);
}
于 2012-11-26T02:53:50.583 に答える
1

もう少しカプセル化されている場合は、これを試すことができます。検証するCSVファイルごとに異なるバリデーターを作成できます。さらに、各行で追加のタスクを実行できるようにするメソッドをいずれかのクラスで作成できます。グローバルに名前が付けられた関数をたくさん持っているよりも、少しすっきりしていてメンテナンスが簡単だと思います。

注:私は明らかに、かなり基本的なバリデーターの例と例外を使用しています。ここでの考え方は、私があなたが従うためのレイアウトを提供しているということです。特定の動作を好きなようにカスタマイズできます。

利用方法

$c = new UserCsvValidator('user_data.csv');

try {
    $c->validate();
}
catch (Exception $e) {
    echo $e->getMessage();
}

実装; 親クラス

<?php

class CsvValidator {

    private $filename;
    private $fh;
    protected $fields = array();

    public function validate__construct($filename, ) {

        $this->filename = $filename;

        // open file
        if ( ($this->fh = fopen($this->filename, 'r')) === false) {
            throw new Exception("could not open file: {$this->filename}");
        }
    }

    public function validate() {
        while( ($row=fgetcsv($this->fh)) !== false) {

            // create hash
            if ( ($hash = array_combine($this->fields, $row)) === false) {
                throw new Exception("invalid row" . print_r($row, true));
            }

            // validate
            foreach ($hash as $field => $value) {

                // determine method call
                $method = "validate_{$field}";
                if (!method_exists($this, $method)) {
                    throw new Exception("validation method not defined: {$method}");
                }

                // validate the field
                if (call_user_func(array($this, $method), $value) === false) {
                    throw new Exception("invalid value for {$field}: {$value}");
                }
            }
        }
    }
}

実装; サブクラス

<?php

class UserCsvValidator extends CsvValidator {

    protected $fields = array('name', 'email', 'address', 'birth_date', 'username');

    // example functions for each field
    protected function validate_name($value) {
        return !empty($value);
    }

    protected function validate_email($value) {
        return strpos($value, '@') !== false;
    }

    protected function validate_address($value) {
        return !empty($value);
    }

    protected function validate_birth_date($value) {
        return date('Y-m-d', strtotime($value)) == $value;
    }

    protected function validate_username($value) {
        return !empty($value);
    }
}
于 2012-11-26T02:46:34.607 に答える