Cactiverecord::findbypk()

i am using findByPk method for retriving the results from the database.

This method is working wrong. i supply the parameter as $id=1 for this statement

echo "<pre>"; print_r(User::model()->findByPk($id));

It gives me the result.

But when i input the parameter as $id=1dsdasad; to the below statement

echo "<pre>"; print_r(User::model()->findByPk($id));

It still fetches the record from the database;

findByPk() method is working like the ‘like’ query!!

I suspect that because PDO is expecting an integer, it’s using PHP’s type conversion functions to change that string into an integer. PHP will just take the leading digits and ignore any remaining junk, so in your case, it’s taking the 1 from the beginning and ignoring everything else.

You can see how PHP converts strings to numbers here.

ok… then how can this be corrected ??

findByAttributes() is also behaving in the same way.

Is there any other way to achieve the results ??

There are several ways.

You could introduce a test to make sure the value you’re using matches the expected format before attempting to do the lookup:




    public function actionTest($id)

    {

        if (!preg_match('/^\d+$/', $id))

            throw new CHttpException(400, 'Invalid request.');


        ...

    }



You might want to wrap the logic up in a separate class and method.

The question is, do you really need to worry about it? Does it matter that "1dsdasad" returns the record with ID 1?

yes i am really worried about this because i am creating an api and i has sensitive data.

i have print the validators using the below statement

echo "<pre>"; print_r(User::model()->findByPk($id)->validators );

Now can you please tell me that how can i use the CNumberValidator to validate this id as input before fetching the results ?

My point is, if the person using your API has access to the record with ID 1, then it doesn’t matter whether they pass the number or that string. No changes are being made.

When updates are performed, each field that can be massively assigned is validated to prevent any badly formatted values. There is no risk when simply fetching the record.

Validators are not used (for this very reason) when fetching records.

The simplest option is to validate the value in your action, as the model isn’t designed to do what you’re attempting.

if you created your crud with gii it will provide you with performAjaxValidation method in your controller you can comment that and in your model you can add the rules you need as simple as that


$this->performAjaxValidation($model);


/**

     * Performs the AJAX validation.

     * @param Post $model the model to be validated

     */

    protected function performAjaxValidation($model)

    {

        if(isset($_POST['ajax']) && $_POST['ajax']==='post-form')

        {

            echo CActiveForm::validate($model);

            Yii::app()->end();

        }

    }

I have done in the same manner. Thanks Keith and alirz23