🎉 سال نو، مهارت نو، مشاوره رایگان نقشه راه برنامه نویسی (آفر ویژه ثبت نام قبل از افزایش قیمت 🔥)
۰ ثانیه
۰ دقیقه
۰ ساعت
۱ محمدرضا
طراحی نرم افزار
میثم حل شده توسط میثم

سلام

بهتر نبود که قابلیت اعتبارسنجی رو طبق اصل single resposibility به صورت یه کلاس جدا یا به عنوان یک فانکشنالیتی (trait) تعریف می‌کردیم و بعد درون فرزندان استفاده می‌کردیم؟

اینکه چه دیزاینی مناسب نرم افزار هستش و اینکه آیا در آینده با این طراحی به مشکل بر می‌خوریم یا نه واقعا جای تمرین داره.

سلام 

دقیقا بهترین کار برای ولیدیشن بهتر اینه که توی کلاس دیگه اینکار رو انجام داد 

به فرض من یک کلاس ولیدیشن نوشتم : 

<?php namespace App\Request;
/**
 * Validation Request
 */
use App\Database\DB;
class Validation
{
    /**
     * @var array
     */
    private $data = [];
    /**
     * @var array
     */
    private $error = [];
    /**
     * @var array
     */
    private $lang = [];
    /**
     * Validation constructor.
     */
    public function __construct()
    {
        if (file_exists(RESOURCE_PATH."lang".DS."fa.php")){
            include RESOURCE_PATH."lang".DS."fa.php";
            if (isset($lang)){
                $this->lang = $lang;
            }
        }
    }
    /**
     * @param array $validate
     * @param array $data
     * @return bool
     */
    public function make(array $validate, array $data):bool
    {
        $this->data = $data;
        if ($this->validationData($validate) == true){
            return true;
        }
        return false;
    }
    /**
     * @param array $validate
     * @return bool
     */
    private function validationData(array $validate):bool
    {
      $validation = true;
        foreach ($validate as $key=>$valid) {
            $items = explode("|",$valid);
            foreach ($items as $item){
                $itemPos = strpos($item,":");
                $param=substr($item,0,$itemPos);
                if ($itemPos == true){
                    $itemParam = $param;
                    $rule = substr($item,$itemPos+1);
                }else{
                    $itemParam = $item;
                    $rule ='';
                }
                if (method_exists($this,$itemParam)){
                    if ($this->{$itemParam}(strtolower($key),$rule) == false){
                        $validation = false;
                    }
                }
            }
        }
          return $validation;
    }
    /**
     * @param string $key
     * @return bool
     */
    private function required(string $key,string $rule):bool
    {
            if (strlen($this->data[$key]) == 0 ) {
               $field =  isset($this->lang[$key]) ? $this->lang[$key] : $key;
                array_push($this->error," مقدار فیلد $field ضروری است! ");
                return false;
            }
            return true;
    }
    /**
     * @param string $key
     * @return bool
     */
    private function number(string $key,string $rule):bool
    {
            if (!is_numeric($this->data[$key])) {
                $field =  isset($this->lang[$key]) ? $this->lang[$key] : $key;
                array_push($this->error," مقدار فیلد $field باید عدد باشد! ");
                return false;
            }
            return true;
    }
    /**
     * @param string $key
     * @param string $rule
     * @return bool
     */
    private function email(string $key, string $rule):bool
    {
        if (!filter_var($this->data[$key],FILTER_VALIDATE_EMAIL)) {
            $field =  isset($this->lang[$key]) ? $this->lang[$key] : $key;
            array_push($this->error," لطفا  $field معتبر وارد کنید ");
            return false;
        }
        return true;
    }
    /**
     * @param string $key
     * @param string $rule
     * @return bool
     */
    private function confirm(string $key, string $rule):bool
    {
        if ($this->data[$key] !=  $this->data['password']) {
            $field =  isset($this->lang[$key]) ? $this->lang[$key] : $key;
            $password =  isset($this->lang["password"]) ? $this->lang["password"] : "کلمه عبور";
            array_push($this->error,"مقدار $password با $field یکسان نیست!");
            return false;
        }
        return true;
    }
    /**
     * @param string $key
     * @param string $rule
     * @return bool
     */
    private function unique(string $key, string $rule):bool
    {
       $db = new DB();
       if ($db->rowCount("SELECT $key FROM $rule WHERE $key=?",[$this->data[$key]]) > 0){
           $field =  isset($this->lang[$key]) ? $this->lang[$key] : $key;
           array_push($this->error,"$field قبلا ثبت شده است.");
           return false;
       }
       return true;
    }
    /**
     * @param string $key
     * @param string $rule
     * @return bool
     */
    private function min(string $key, string $rule):bool
    {
    if (strlen($this->data[$key])<$rule){
        $field =  isset($this->lang[$key]) ? $this->lang[$key] : $key;
        array_push($this->error,"$field نباید کمتر از $rule کاراکتر باشد ");
        return false;
    }
    return true;
    }
    /**
     * @param string $key
     * @param string $rule
     * @return bool
     */
    private function max(string $key, string $rule):bool
    {
        if (strlen($this->data[$key])>$rule){
            $field =  isset($this->lang[$key]) ? $this->lang[$key] : $key;
            array_push($this->error,"$field نباید بیشتر از $rule کاراکتر باشد ");
            return false;
        }
        return true;
    }
    /**
     * @return array
     */
    public function getError():array
    {
        return $this->error;
    }
}

این کلاس از طریق متد make ولیدیت‌ها و همچنین دیتا رو میگیره و اون‌ها رو ولیدیت میکنه و اگر خطایی وجود داشته باشه  اون رو برمیگردونه در غیر اینصورت true رو برمیگردونه 

و نحوه استفاده از اون هم به این شکل : 

   $validation = new Validation();
        $rules = [
            "name"=>"required|min:3|max:100",
            "email"=>"required|email|unique:users",
            'password'=>"required|min:8|max:32",
            'confirm-password' => "required|confirm"
        ];
        if ($validation->make($rules,$data) == true){//code}

چیزی شبیه به ولیدیشن فریم ورک لاراول رو نوشتم!

شما هم به همین صورت میتونید چنین کاری رو حالا بصورت تریت و یا کلاس پیاده سازی کنید و اصولی ترش همینکار که هر کلاس رو جدا تعریف و ازش استفاده کنیم.

بهترین پاسخ
میثم ۲۲ تیر ۱۳۹۹، ۱۹:۵۹