How to verify the uniqueness of ThinkPHP5.0 data update verification.

simple small projects can be validated normally when the data is inserted into the database when the validation field is customized. If you want to use this set of validation methods when updating data, you need to verify whether a field, such as the catename field, exists, and then whether it is the only one in the database. ThinkPHP5
the following custom validation is the code: (very simple)
class Admin extends validate
{

protected $rule = [
    "catename" => "unique:cate|require|length:4,25"
];
protected $message = [
    "catename.require" => "",
    "catename.unique" => "",
    "catename.length" => "3-5",
];

}
then the data update code: model layer
/ / column modification

public function edit($data)
{

    $validate = new Admin();
    if ($validate->check($data)) {//
        $num = Cate::isUpdate(true)->save($data);
        return $num;
    } else {
        return $validate->getError();
    }
}

there is a problem here: when I do not make changes, the data will definitely fail to change! Return the number of rows that have no effect because no changes have been made! But if judged that he was executing it over there! The execution was also successful! Just like I modified the data is the "menu bar", I do not modify the original into it to verify success! I vaguely remember that the update operation is to delete the original data and re-insert the data, then my judgment of uniqueness is invalid! But how can I tell if he is the only one when I update it? Xiaobai also asks for your comments!

Php
Mar.21,2021

The

problem should be that the uniqueness decision at the time of update is to exclude itself.
I remember seeing the code that tp5 validates this block, which cannot be implemented alone in the valide validator class, because there is no way to get the passed parameters in this class. But it can be implemented in controller, but there is no detail in the document. I have specific code on how to implement it in the comments below their official document, which you can refer to or help post.

< hr >

post it yourself:

the document is too crude, and you have to look at the source code. 'name' = >' unique:user,status=1&account='.$data ['account'] , this kind of document can only be put in controller , and you can define rule and message . You can't pass the relevant values in a separate validate class. The
rule is: unique: [model class name (or table name)], [the field to be verified (either contains the = sign or ^ sign, but you must add your own condition, don't think that the name itself will not be added if there is a name)], [fields to be excluded], [Primary key (which can be left empty)]
example:

$id = $this->request->post('id');
$shopId = session('shop_id');
$name = $this->request->post('name');
$sort = $this->request->post('sort', 0, 'intval');
$postData = [
    'name' => $name,
    'sort' => $sort
];
$rule = [
    'name' => 'require|unique:ArticleCategory,shop_id=' . $shopId . '&name=' . $name,//
    'sort' => 'number'
];
$message = [
    'name.require' => '',
    'name.unique' => '',
    'sort.number' => '',
];
$validate = new Validate($rule, $message);
if (!empty($id)) {
    $validate->scene('edit',
        [
            'sort',
            'name' => 'require|unique:ArticleCategory,shop_id=' . $shopId . '&name=' . $name . ',' . $id
        ]);
    $validateRes = $validate->scene('edit')->check($postData);
} else {
    $validate->scene('add', ['sort', 'name']);
    $validateRes = $validate->scene('add')->check($postData);
}
if (true !== $validateRes) {
    $data['msg'] = $validate->getError();
    return json($data);
}

I'm confused about your description. You want to do some legal thinking and make your speech simple, so that we can help you find the problem. no, no, no.


I think the database table field is set to unique. If it exists, the insert fails directly. If you want to advanced, then according to the user input to query first, there is a friendly prompt to return. This should not be difficult for you.


Thank you for the comments


my question is that tp5.0.19 cannot use the above method, but read this article: https://www.cnblogs.com/PHPak.;
add a hidden field to the form form of the editing page: the id field name in the < input type= "hidden" name= table "value=" get passed id value "> (be sure to note that name has the same name as the primary key), and then define the relevant rules in the validator class. Instead of defining verification scenarios, add and edit using the same rule:
class Admin extends Validate
{
protected $rule = [
[
'account',' require | length:3,15 | checkChanese: | checkSpecial: | unique:admin,admin_account', 'account must be entered | the account length is between 3 and 15 characters | the account cannot contain Chinese characters | the account cannot contain special characters | the account already exists, Please re-add']
]
}
validation in the model:
/ / perform validation
$validate = validate ('Admin');
if ($validate- > check ($data)) {/ / Verification passed.} else {/ / Verification failed.}
hand test is available. I hope I can help you


if you don't use a stand-alone validator, the upstairs method is feasible.
my version is 5.1.x. Using the stand-alone validator, you can reset the rule in the update method by excluding checking the currently updated data ID.
I flipped through the document several times, and there seemed to be no case of verifying that the scene could be passed parameters, so I wrote it in this barely elegant way.


unique

$validate = new Validate([
    'name'  => 'require|max:25',
    'mobile' => 'unique:user'
]);
$validate->check([
    'id' => $data['id'], //userid
    'name' => 'xxx',
    'mobile' => '13888888888' //
])

where this function is implemented in the thinkphp5 source code

//  \think\Validate 
        $pk = isset($rule[3]) ? $rule[3] : $db->getPk();
        if (is_string($pk)) {
            if (isset($rule[2])) {
                $map[$pk] = ['neq', $rule[2]];
            } elseif (isset($data[$pk])) {
                $map[$pk] = ['neq', $data[$pk]];
            }
        }
        if ($db->where($map)->field($pk)->find()) {
            return false;
        }
MySQL Query : SELECT * FROM `codeshelper`.`v9_news` WHERE status=99 AND catid='6' ORDER BY rand() LIMIT 5
MySQL Error : Disk full (/tmp/#sql-temptable-64f5-1eb6bb1-25fa.MAI); waiting for someone to free some space... (errno: 28 "No space left on device")
MySQL Errno : 1021
Message : Disk full (/tmp/#sql-temptable-64f5-1eb6bb1-25fa.MAI); waiting for someone to free some space... (errno: 28 "No space left on device")
Need Help?