2015-06-03

If you're asking, "What's Yii?" check out my earlier tutorial: Introduction to the Yii Framework, which reviews the benefits of Yii and includes an overview of what's new in Yii 2.0, released in October 2014.

In this Programming With Yii2 series, I'm guiding readers in use of the newly upgraded Yii2 Framework for PHP. This tutorial is our second part, looking at Yii2's validators. Validators simplify the code needed to validate input, i.e. verify conformance or non-conformance of data input, typically from users via web forms. Specifically, we're going to explore some of the built-in specialty validations that are common to web development.

Here's a list of the built-in Yii validators and links to documentation that we're going to explore:

CaptchaValidator: Validates a CAPTCHA form verification field.

CompareValidator: Compares two values from the form or a constant, e.g. x must be less than 99.

EmailValidator: Ensures a value is a valid email address.

ExistValidator: Ensures that a value exists in another table.

FileValidator: Ensures existence of an uploaded file.

ImageValidator: Validates image and image properties.

RangeValidator: Ensures a value is within a list of values.

RegularExpressionValidator: Performs validation against a condition defined by a regular expression.

UniqueValidator: Ensures value is unique within a table, such as an email address.

UrlValidator: Ensures value is in URL format, e.g. http://yourdomain.com.

I'm going to guide you through examples of each of these validations using the Hello application codebase from past tutorials and a couple from our Building Your Startup Series which also uses Yii2. Use the GitHub links on this page to get the code.

Just a reminder, I do participate in the comment threads below. I'm especially interested if you have additional ideas or want to suggest topics for future tutorials. You can also reach me @reifman on Twitter or email me at Lookahead Consulting.

What Is a Validator?

If you're a web developer, you likely know that user input can't be trusted. For example, users can use SQL injection techniques to try to run queries that change or expose passwords. Someone once leveraged SQL injection against my open source PHPList installation and managed to discover one of my passwords (PHPList stored these in plain text). More commonly, you just want to ensure that the data users provide conforms to the types, forms and ranges of your application.

Building validators in PHP by hand takes time. The Yii Framework provides a ton of baseline validation features so there's no need to build them from scratch. But, if you need some custom extensions, that's straightforward as well.

Validations are yet another reason why I think it always makes sense to build applications on a web framework such as Yii rather than vanilla PHP.

In earlier episodes, we've also talked a lot about Yii's code generator, Gii. One of the benefits of Gii is that it will write the appropriate validation rules for your models based on the SQL type definitions in the schema. This is a big time saver.

You may want to go back to our last episode to read more on Yii2's basic type validations.

Now, let's begin looking at the next set of Yii2's built-in validators.

The Next Set of Validators

The Captcha Validator

Let's begin with CaptchaValidator which checks that there is a proper response to a CAPTCHA verification field. CAPTCHAs help ensure that a human is filling out the form, hopefully keeping automated scripts from submitting it.

Here's an example of the Yii Captcha in action:

In our Hello codebase, I've simplified our sample form to just include the Thought and Captcha fields for now. Here's a look at the model code's rule definitions:

The captcha isn't part of our database schema—it's only used to verify the form. Therefore, I've added an attribute to the model for it, e.g. public $captcha;.

Here's the view code for the form. We have to include the Captcha library at the top.

Here's what the Captcha validation looks like in action:

If you click the Captcha, Yii will generate a new image.

The Compare Validator

Now, let's move on to the CompareValidator. This validator compares two values from the form or a single form value to a constant, such as x must be less than 99.

For this example, I want to make sure that user input for rank is greater than zero but less than or equal to 100.

First, I'll add the input field back to our form for the rank attribute:

Then I'll add two compare validation rules to our model:

You can see a full list of available comparison operators here.

Here's what our form looks like when the user submits an invalid attribute:

If we want to provide the specific constraint rules in one error message, Yii Validators allow you to customize the error shown to the user, like this:

Implementing this is quite simple with the addition of the message attribute:

Updating Our Schema to Test More Validations

For some of these next validation tests, I'm going to ask you to add some fields to the database.

In \migrations\m150219_235923_create_sample_table.php, we'll add some new fields to test the next set of validators: email, URL, filename, etc.

Then run the migration down to drop the table and then up:

We're now ready to test the email and URL validators.

Email & URL Validators

The EmailValidator ensures a value is a valid email address and the UrlValidator ensures a value is in URL format, e.g. http://yourdomain.com.

It's quite simple to create rules for our new email and URL fields:

Here's the view code for the form. Note how I'm using custom labels to improve the form usability:

Here are the validators in action:

These are obviously highly useful for web applications.

The Exist Validator

The ExistValidator is super useful in certain scenarios. It can ensure that a value exists in another table. And it can be used in a variety of ways—here are some examples given in the documentation:

The Yii documentation highlights that Exist can be used to "verify that a foreign key contains a value that can be found in the foreign table."

For our example, I'm going to create a rule that checks that the email address in the form already exists in our registered User table. To do this, we use the targetClass which tells Yii which Class (or Model table) to look up the user's email address in for validation.

Here's the rule definition—note the inclusion of our User model at the top:

That instructs Yii to query the User table to ensure that the provided email address matches a previously registered user.

Here's what it looks like in action:

You can learn more about the Exist validation and its permutations here.

The File and Image Validators

Next, I'll show you examples of the FileValidator, which ensures existence, MIME-type and size of an uploaded file, and the ImageValidator, which validates the image and its properties.

To explore the File and Image validators, let's let's look at an example from the Building Your Startup With PHP series: User Settings, Profile Images and Contact Details. In that episode in the UserSettings model, we're allowing users to upload a file for their profile image.

The image attribute accepts the uploaded file:

The FileValidators are ensuring that the image ends in a proper image extension and is less than 100,000 bytes.

The ImageValidator also verifies the extension type as well as the width and height ranges for the image.

Here's an example of errors generated by uploading an image whose dimensions are larger than 400 x 400 pixels:

That's my assistant up above who used to like to copyedit my tutorials.

The Range In Validator

There's also the RangeValidator which ensures a value is within a list of allowable entries.

For our example, let's add the field for censorship back into the form:

Then, we'll add a RangeValidator to match the response to a yes or no string:

Here's an example of the RangeValidator in action:

The Regular Expression Match Validator

Next, let's look at the RegularExpressionValidator, which performs validation against a condition defined by a regular expression.

In our example, I'm using the following regex to match complete sentences with alphabetic characters. This means they must end with either (!, ? or .) and have no numeric characters.

Here's an example of user input that fails the test because of the numbers and the lack of a trailing punctuation mark:

Here's a valid sentence:

You might also be interested in Eight Regular Expressions You Should Know (Tuts+) as a reference for common regex patterns.

The Unique Validator

Finally, let's review the UniqueValidator, which ensures that a value is unique within a table, such as an email address or a slug.

I reviewed SluggableBehavior earlier in this series, which offers its own built-in uniqueness support. However, let's look at a couple more examples from the Building Your Startup With PHP series.

In the codebase for Meeting Planner (from the more recent tutorial episodes) in the Place model (\frontend\models\Place.php), we use the unique validator in several ways:

First, we use the unique rule with the slug to augment SluggableBehavior, which is redundant; but you can see the validation format.

Second, we're checking that the results of the Google Places Autocomplete searchbox result in the hidden field for google_place_id being unique in that it doesn't yet exist within the Places table yet. We're essentially preventing duplicate Google Place IDs.

The significant piece of this is that Yii2's unique validator allows us to enforce uniqueness on the visible field (searchbox) while validating it on the secondary column returned via AJAX from Google (google_place_id).

Third, we're ensuring that name and full_address are unique together. In other words, duplicate places names are okay. There can be a bazillion Starbucks. However, we do not want anyone entering the same Starbucks location twice.

Note: Starbucks coffee is not an effective stimulant for software developers. I encourage you to frequent independent coffeehouses.

Here's an example of this in action:

What's Next?

I hope that you agree how simple and useful Yii2 validators are for web development. I simply can't imagine ever returning to vanilla PHP development without the aid of a framework.

Watch for upcoming tutorials in my Programming With Yii2 series as I continue diving into different aspects of the framework. In the next episode, I'm going to review Yii2's advanced validation features such as:

Conditional validation to perform a validation rule only if a specific event is true

Custom validators to create essential validations beyond what Yii offers out of the box

Client side validation to make use of Yii's built-in ActiveForm JavaScript validation without requiring a page refresh

AJAX validation for implementing server side AJAX validations to extend Yii's client-side JavaScript page validation capabilities.

Validation events to override validation or perform specific functionality before and/or after validation

Defining scenarios to selectively apply rules for certain situations

Ad Hoc validation to use validation rules independently of form submission

I welcome feature and topic requests. You can post them in the comments below, reach out to me @reifman on Twitter, or email me at Lookahead Consulting.

If you'd like to know when the next Yii2 tutorial arrives, you can also check my Tuts+ instructor page. It always includes links to my articles immediately after they are published.

Related Links

Yii2 Guide to Validating User Input

Yii2 Guide to Core Validators

Yii2 Validators (Documentation)

Yii2 Developer Exchange, my own Yii2 resource site

Show more