Difference between #1 and #2 of Safely checking if a model class exists (without exploding)

unchanged
Title
Safely checking if a model class exists (without exploding)
unchanged
Category
How-tos
unchanged
Tags
error handling, validation
changed
Content
When is this needed?
------------------

While rewriting the [PcReportContent
extension](http://www.yiiframework.com/extension/pcreportcontent/
"PcReportContent extension") I'm maintaining I've bumped to a
challenge. This wiki was born out of it.it and below are its
details.

This **PcReportContent** extension is about reporting inappropriate content by
users, to some predefined email address. This works using a widget that is
plant-able in any location on the website, and which gets a 'model name' and
'model id' when rendered. It plants this information in the report form so when
the user submits the form, it reaches the server side with this information,
along of course with the user text explaining what's wrong with the content its
reporting of. This allows for several such 'report content' boxes (=widget
instances) to live (happily ever after) one along side each other on the same
page. Each contains different form values (meaning model name and id), in
accordance to where it was 'rendered'. 

**Here's the problem**: When processed on server side, the server side
counterparts needs to validate the client side data, as any data from client
side is never to be trusted, right? Ok, so my initial validation on the _model
name_ was a 'class_exists()' firing. Problem is, if the class does not exists,
without rather complex changes to Yii's auto loader or to PHP's environment
(silencing PHP errors - another thing you don't want to operate under - you
*want* to be aware of problems in your code/application) a PHP Error (WARNING)
will be triggered and the application operation will abort. I wanted to catch
this situation and return nicely to client side rather then this abortion. 

_Just to complete the picture regarding webite security, with the [input
extension](http://www.yiiframework.com/extension/input/ "") deployed,
I think I'm pretty safe with regard to malicious user tweaking the form values_.

Suggested solution
------------------

Since the script will end with a PHP error, not with a PHP Exception being
thrown, a simple try-catch using is not an option.

Also note that I **do** want to check the presence of the model class using
Yii's auto loader so using _class_exists(MyClass, **false**)_ (as suggested
[here](http://www.yiiframework.com/forum/index.php/topic/22790-check-if-model-exists/page__view__findpost__p__111444
"")) was not an option as well.

**Solution**: The solution was to temporarily provide an error handler method
that is 'operative' just when the validation of the model class takes place.
Since what will happen is that Yii will attempt to load the class, using
'include()' at the end of the process, if the class name does not exists, a PHP
warning will be thrown. PHP WARNINGs are 'catch-able' by custom error handler
methods. So, it all boils down to this setup:



~~~
[php]
// validate we have modelName, modelId
set_error_handler(array($this, 'tempErrorHandler'), error_reporting());
if ((!class_exists($_POST['model_name'])) || (empty($_POST['model_id']))) {
    // if this block is executed its since the model_id was problematic.
    // log and return with an error to client side
    Yii::log(...);
    echo "Error occurred";
    Yii::app()->end();
}
// purge the temporary error handler
restore_error_handler();

// and down the same class (its a controller class) we have the custom error
handler method
public function tempErrorHandler($errno, $errstr)
{
    Yii::log(...);
    echo "Error occurred";
    Yii::app()->end();
}
~~~