An avid proponent of Yii Framework and open source software, Charles has offers eBook versions of every book published, with PDF and ePub iles available ?. Like most PHP frameworks, Yii implements the MVC (Model-View-. Controller) architectural pattern and . 9bestthing.info . Yii excels over other PHP frameworks in that it is efficient, feature-rich and clearly - php YiiRoot/framework/bestthing.info webapp WebRoot/testdrive books, while in other languages, the word may not have different form (such as Chinese).
|Language:||English, Portuguese, Japanese|
|ePub File Size:||29.69 MB|
|PDF File Size:||8.31 MB|
|Distribution:||Free* [*Sign up for free]|
Qiang Xue, creator of the Yii framework; Alexander Makarov, and the .. Next, I converted the MultiMarkdown source to a PDF using Pandoc, which sup- ports its . Please help Bill Keck by spreading the word about this book on Twitter! The Yii 2 PHP framework is highly scalable and extensible, and .. in order to avoid line breaks from the wordwrapping in PDF and other formats. The Yii framework also uses the latest features of PHP, like traits and All the content and graphics published in this e-book are the property of Tutorials Point (I ).
I never dreamed at the time that I would end up writing a book about one of them. Anyway, we collectively researched everything we could find on the major PHP frameworks. I personally read all of the documentation and we had long engineering discussions about what we thought would work. You cant imagine my frustration with the fact that I read all this documentation and walked away from it feeling less knowledgeable than before I started reading it.
Our team of programmers did have a preference however. They felt that Yii 1. This was the version of Yii that was available at the time we were deciding this. So the team adopted that framework and never looked back. They loved it. I, on the other hand, remained frustrated.
Yii - tutorialspoint.com
Since I was only a novice programmer, I really struggled to learn it. I didnt find it very intuitive. Especially after comparing it to other frameworks, where they were trying so hard to make everything integrate beautifully, the architecture of Yii just seemed ugly. I got so frustrated at one point, that I started looking for another option. Other Options I would find some beautifully written documentation for a new framework and run it past the team.
I always got the same response. The team was happy with Yii. They told me it might be difficult to learn, but it was easy to use, once you knew how it worked. Because of that, I committed myself to learning it.
It was slow going and a rough ride. I wasnt getting it. I was working through chapter 10 in a book on Yii 1.
Too many roads seemed to go nowhere. Then a miracle happened. Yii 2 Arrives I found out about the Yii 2 alpha. I was curious to see what the differences were in Yii 2, which had been 3 years in the making at that point. So I jumped in and to my utter and complete surprise, I instantly connected with it. I understood the structures.
I could write code that actually worked! What a great feeling that was. I have personally found Yii 2 to be the most intuitive and elegant of all the PHP frameworks that I have studied. I have so much enthusiasm for it that I want to share it with every programmer I know, and even those I dont know, so it has motivated me to write this book.
With Yii 2, even as a beginner, I was able to stand up a working website that has a data-driven user model, with both a frontend and a backend. Right out of the box, I get a working user model, with forgot password functionality, which is also integrated with Bootstrap for mobile-responsive design, without having to do any programming whatsoever.
How cool is that? Although I was a beginning programmer when I was studying the PHP frameworks, I did have experience working with databases and this is one area in my opinion where Yii 2 really shines. I pronounce that with a soft g, but I have no idea if that is the right way to say it or not.
Anyway, Gii analyzes your database tables and automatically builds PHP models from them. Not only that, but it analyzes the relationships between tables and automatically generates the relational code into the models. Not only is this a time-saver, but this also gives you very consistent code because it is always done the same way and it helps you adopt this discipline.
Its worth mentioning that other frameworks work exactly the opposite way. With them, you build the model first, then do a migration to the database to create the table and corresponding columns.
So the big difference is that you are building your data structure piecemeal as you go along, whereas in Yii 2 you have the option of having a more complete data structure to begin with. Both approaches work, however they represent drastically different workflows. The reason why I say this is that although democracy is probably the best system politically, imagine a world where each developer makes up their own data structure and implements it.
How consistent would that be? What if the right hand didnt know what the left hand was doing? In larger teams, this is a recipe for chaos. This is why enterprise development teams usually have a database administrator, also known as the DB, and only they can create or delete data structure. DB-First Approach Since Yii 2 allows you to essentially import the models from the data structure, you can start your project by really thinking through your data structure.
Overall I like to avoid talking about too much theory because the time is better spent working through hands-on examples, but I think its worth taking a moment to think about what a well thought-out data structure really means.
Whether you are a single developer or part of an enterprise level team, you are essentially being given the same task, the same overall mission. We use a PHP framework to make this task easier, and by saying that, we are admitting upfront that its not an easy task. Why is that? The database is a very reliable and consistent piece of software, which allows us to create a relational data structure.
MySql Throughout this book we use Mysql as the database, which, in addition to being free, is capable of powering enterprise data for web applications. Chapter One: Introduction Because of the structure of the database, with its indexes and primary keys, a database can serve data very efficiently.
In the simplest terms, this means it is very fast. Its also very deep. It can hold millions of records, which can be retrieved, if structured properly, in milliseconds.
With this change, our application now knows that it needs to look in a ile called db. Parameter coniguration In a manner similar to our database coniguration ile, Yii also lets us use a parameter ile where we can store all of the noncomponent parameters for our application. Since the basic app doesn't make this ile aware of its environment, we'll change it to do that as follows: Typically, we'd break them down into four distinct environments: This environment is where all of our local development occurs.
Typically, developers have complete control over this environment and can change it, as required, to build their applications. Normally, we'd deploy our application to this environment in order to make sure that our code works in a production-like setting; however, we normally would still have high log levels and debug information available to us when using this environment.
This is a separate environment that we'd provide to our client or business stakeholders for them to test the application to verify that it does what they want it to do. This is where our code finally gets deployed to and where all of our users ultimately interact with our application. Since our local environment is going to be called DEV, we'll create it irst: We'll start by creating our DEV environment folder from the command line: Next, we'll create our dev database coniguration ile in db.
For now, we'll stick with a basic SQLite database: Next, we'll create our environment coniguration ile in env. If you recall from earlier in the chapter, this is where our debug lag was stored, so this ile will look as follows: Finally, we'll create our params. As of now, this ile will simply return an empty array: From the command line, we can do that as follows: To do this, we'll set custom variables in our web server coniguration that will pass this option to Yii.
With Apache, we typically have a VirtualHost block that looks as follows: At the most basic level, our application isn't doing anything different from what it was when we irst ran the composer create-project command. Despite not doing anything different, our application is now signiicantly more powerful and lexible than it was before our changes. Later on in the book, we'll take a look at how these changes in particular can make automated deployments of our application a seamless and simple process.
Components and objects There are two base classes that almost everything in Yii2 extends from: In Yii1, components act as service locators that host a speciic set of application components that provide different services for the processing of requests. Each component in Yii2 can be accessed using the following syntax: To improve performance in Yii2 applications, components are lazy-loaded or only instantiated the irst time they are accessed.
This means that if the cache component is never used in your application code, the cache component will never be loaded. For instance, if we want to bootstrap the log component, we can do that as follows: For more information on service locators and components, ensure that you read the Deinitive Guide to Yii guide located at http: The Object class is the base class that implements the property feature. Combined, this makes objects in Yii2 extremely powerful. The object class is extremely powerful, and many classes in Yii extend from it.
In Yii2, aliases always start with the symbol so that Yii knows how to differentiate it from a ile path or URL. Aliases can be deined in several ways. Summary In this chapter, we went over how to create new Yii2 applications via composer. We also went over the basic coniguration iles that come with Yii2 as well as how to conigure our web application to load environment-speciic coniguration iles. Finally, we also covered components, objects, and path aliases, which are fundamental to gaining mastery over Yii.
In the next chapter, we'll cover everything you need to know in order to become a master of console commands and applications. These tasks may include things such as generating reports, sending e-mails via a queuing system, or even running data analysis that would cause a web-based endpoint to timeout.
With Yii2, we can build these tools and scripts directly into our application by writing console commands or even complete console applications. Coniguration and usage The basic structure of Yii2 console applications is very similar to the structure used in web applications. Entry script Before moving on to the coniguration iles themselves, let's take a look at the console entry script, which is part of the ile called yii. This entry script serves as the bootstrapper for all our console commands, and in general, they can be run by calling this: We can change this by replacing yii with the following code block: Yii2 also provides a yii.
If you're following along on a Windows computer, ensure that you change yii. With our entry script iles conigured, we're ready to take a look at our application coniguration iles. This script is used by Codeception, a testing framework that is used to run unit, functional, and acceptance tests in Yii2. We'll cover how to conigure and use this entry script and Codeception in Chapter 10, Testing with Codeception.
In fact, the only major difference between our web and console coniguration is the explicit declaration of our console command namespace and the explicit declaration of the test alias, which deines where our test iles will be located. Because of this lexibility, the console coniguration ile expects us to declare the test alias explicitly so that we can run our console tests.
From the command line, we can easily change the environment by exporting a variable: By adding this command to either of these iles, the next time we log in to our shell, this variable will automatically be exported. Go ahead and give it a try! Log out and log in to your shell again and run the following: For example, if we want to see what subcommands exist for the cache command, we can run the following: For example, if we wanted to lush the entire cache for our application from the console, we could run the following command: The following cache components were processed: This option is especially useful when creating applications that have both a frontend and a backend that may contain different caches or database components.
Built-in console commands Now that we know how to run console commands, let's take a look at the built-in commands to see how they work. As shown previously, Yii2 has seven built-in console commands: During the development of our application, we're likely to use all seven in order to make our application more robust.
Let's take a look at each one in more detail. The help command The irst command built in to Yii2 is the help command.
This command is called using the following: The cache command The third built-in command in our toolbox is the cache command. The cache command provides the functionality to lush caches that are generated by our application. The following caches were found in the system: In our default application, only one cache is predeined: Using the output of the previous command, we can clear the cache component by name by running this: The following cache components will be flushed: This may be problematic when you need to automate the use of a command, such as on deployment.
When running commands noninteractively, additional arguments may be required. Ensure that you reference the help command to determine what arguments you need to pass when running noninteractive commands. Yii2 will maintain a cache of the currently active db component the database and the database schema when instructed to.
When making schema changes, such as when applying new migrations, we need to clear this cache so that Yii2 becomes aware of our updated database structure.
We can clear the database schema cache by running this: The ixture command When testing our application, we'll often want to set up our database such that our tests always run in a predictable and repeatable way.
One way in which we can do this is by creating ixtures, which will represent database objects in our application for testing. When using ixtures, our typical test low is as follows: Apply database migrations. Execute our test cases in the following manner: Load our database fixtures. Execute a specific test. Unload our database fixtures. Repeat as required until all tests have run. Additionally, the yii2-codeception package provides additional support for the loading and unloading of ixtures when our tests run.
In Chapter 10, Testing with Codeception, we'll cover how to creature new ixtures and how to integrate them with Codeception.
The Gii command The next set of commands in our toolbox is the Gii command. If you are familiar with Yii1, Gii provides the functionality to generate controllers, models, forms, and even basic CRUD functionality.
In Yii2, Gii has been extended from a web application module to both a web and console application and has been enhanced to include additional features as well.
The Gii module in Yii2 provides these console commands to automatically generate code: Each of these commands, when supplied with the right options, will generate the respective item identiied by the subcommand.
For a complete list of requirements and options, ensure that you use the help command on the Gii subcommands. As a development tool, Gii has the ability to arbitrarily generate and override existing code in your application.
For security purposes, you should conditionally load the Gii module only in your development environment. Moreover, the Gii module itself should never be deployed to your production environment. For this reason, it is advised that you only load the Gii module in the require-dev section of your composer.
The require-dev section is a special section within our composer. By default, running Composer will install all packages in our require and require-dev sections. In production environments, we will want to exclude our development environments by passing the --no-dev lag to our Composer installation command. For more information on the Composer CLI, ensure that you reference the Composer documentation at https: In Chapter 11, Internationalization and Localization, we'll go into more depth about how to use these commands to generate PHP message iles and.
We'll also cover the use of the Yii:: The migration command The inal built-in command set with Yii2 is the migration command. The migration commands provide functionalities to generate, apply, revert, and review database migrations. This tool provides these subcommands: For now, use the. Creating console commands Now that we know what built-in commands Yii2 provides, let's start adding our own commands.
If this folder doesn't exist yet, go ahead and create it: First, we'll create a new ile called BasicController. Now, let's write some PHP code. First, we need to declare the namespace that our BasicController lives in.
Next, we'll declare our controller class as follows: Finally, inside our class, we'll create an actionIndex method that will simply output HelloWorld and then gracefully return with a successful error code. By default, the actionIndex method is the method that is called when an action is not speciied to a controller: Now, if we run the help command, you can see that our command appears in the list of available commands: HelloWorld Generating help information While we can now run our commands, the help command for both the global help menu and the action help menu currently doesn't provide any useful information.
In Yii2, this information is extracted directly from the document block comments also known as DocBlock comments that are used before our BasicController class and our actionIndex method. For instance, consider that we add the following before our class declaration: Take, for instance, the following method of our BasicController: Arguments serve as the data that we provide to your actions.
On the other hand, options allow us to specify additional coniguration for our controller in general.
Each console application we create and use may have separate options that we can set. Ensure that you reference the Yii2 documentation for that class and use the help command to determine what options are available for each command.
A step by step guide to learning Yii 2 for beginners
Without any arguments, this command will throw the following error, indicating that the name parameter is required: Missing required arguments: Alice lives in Chicago. By providing a default value to the city parameter, that option is not required for our command to be executed. However, if we passed a value as the second parameter, it would override our default value as expected: Alice lives in California.
Ensure that you wrap any strings that use special characters in quotes to ensure that the full argument is passed to your application.
Take, for instance, the following method: From the command line, we can specify an element as an array by representing it as a comma-separated list: If you need to pass a multidimensional array of data from the command line, you can pass a path to a coniguration ile instead and then load that ile inside your controller action.
While returning from our controller action isn't strictly necessary, it's considered a best practice so that our shell can be notiied whether our console command has been executed successfully or not. By convention, an exit code of 0 indicates that our command ran without errors, whereas any positive integer greater than zero would indicate that a speciic error occurred. The number returned will be the error code that is returned to the shell, and it can be used by our end users to reference our application documentation or support forum to identify what went wrong.
Suppose, for instance, that we wanted to validate one of our inputs without diving into custom forms and validators. If that integer is less than zero, we could return an error code that our documentation would be able to reference: If you have more than one return code, it is considered a good practice to deine meaningful constants in your controller to identify your error code. Before we can use this helper, we need to import it into our class: While both methods will format text, the ansiFormat method can be used to dynamically combine multiple strings with different formats: We're done!
We also covered the seven built-in console commands in brief. Additionally, we covered how to create our own console commands, how to pass parameters to our command, how to return values properly from within our code, and how to format the output of our commands.
In the next chapter, we'll expand our mastery of Yii by learning how to use and write migrations, how to use database access objects DAO , and how to use Yii's built-in Query Builder. In this chapter, we'll cover how to connect to different databases, write database migrations to instantiate our databases, use database access objects DAO , and use Yii2's built-in Query Builder.
We'll also cover the basics of powerful tools such as data providers and data widgets as well as how to use Yii2 to replicate and load balance access to our databases. Through this class, we can connect to a variety of different database types, ranging from local SQLite databases to clustered MySQL databases.
The simplest way to establish a connection to a database is to create a SQLite database connection, as follows: We can keep our application DRY by putting our database coniguration into the db component of our web or console coniguration ile.
As an example, establishing a SQLite connection in this ile will be done as follows: Furthermore, since Yii2 loads components only when required, it can keep our application lean and performant. In Yii2, components are only loaded when required. This process is often called lazy loading. Unless a component is preloaded, Yii2 will not create an instance of that component until it is irst used.
After being initially instantiated, Yii will then reuse the same component across your application rather than creating multiple instances of that component. Lazy loading is one of the primary reasons Yii is so performant. With our database coniguration stored within our coniguration ile, we can now access the database connection, as follows: As stated earlier, Yii2 can connect to several different database types.
A few examples of the data source names DSNs that Yii2 supports are listed here: More information on these base drivers can be found within the PHP manual at https: More information on this driver can be found in the PHP manual at https: Note that Yii2 will not be able to connect to any database unless the appropriate PHP drivers are properly installed and conigured. If you aren't certain which drivers you have installed, the native phpinfo function can output a list of all the currently installed PHP extensions.
Within the db component, simply specify the username and password attributes that are appropriate for your database. Additional coniguration options In addition to the basic db component options listed previously, Yii2 also provides several additional options that can be used to either enhance the performance of your application or deal with a known issue within the native PHP drivers.
While many of these options can be found in the Yii guide and the API documentation, some of them will most likely be used more often than others.
By default, Yii2 will try to use the native prepare support built into the native PDO driver. To improve the performance of our application, we can set this value to true and allow Yii to cache commonly executed queries.
In an application that mostly performs read actions, enabling this attribute can greatly increase the performance of your application.
To completely enable this component, however, the additional properties we'll mention now must be set as well. If unset, this will simply default to the cache component in our application.
By default, the query cache will be valid for 3, seconds, or 60 minutes: Before Yii accesses the database, it will often need to determine the database schema. This schema information is used to assist Yii when running validators and working with relational models, such as related Active Record models. Any change to the underlying data or schema in your database may cause your application to return bad data or crash entirely.
Writing database migrations When building and maintaining modern web applications, the underlying structure of our database may need to change to account for changes in requirements or scopes.
To ensure that our database schema can evolve in tandem with our source code, Yii2 provides built-in support to manage database migrations. Using database migrations, we can treat our database as an extension of the source code and easily change it when our source code changes.
When paired properly, we can often write our migrations in a way that enables them to be run across a variety of database types. For example, when working locally, we might need to use a local SQLite database even if our application will ultimately run on a MySQL database.
At the heart of this class is a variety of different schema types that Yii2 will be able to properly map to the appropriate data type within our database. For a complete list of the available constants made available by the Schema class, ensure that you refer to the Yii2 guide at http: Within our migrations, we can call any of these constants by running this: Using the source code from the previous chapter as a starting point, we'll do this by running the following from the command line: Depending upon the ile permissions on your system, Yii2 may not be able to create the migrations folder if it does not exist.
When running migrations, Yii2 will execute them in the order in which they were created. Because of this naming convention, any migration that you create will have a distinct and unique ilename.
If you're following along, ensure that you're working in the ile that was created from the. These two operations correspond to one of four functions: The up and down methods are the base methods required to run migrations and will execute any database command issued inside them even if there is an error. Alternatively, we can use the safeUp and safeDown methods, which are functionally identical to the up and down methods, with the exception that the entire operation is wrapped within a transaction.
If our database supports transactions, running our migrations from the safe methods can help us catch migration errors at runtime before an error can cause problems with our entire database. Because of the additional safety they offer, safeUp and safeDown should be our go-to methods when writing migrations. Additionally, if safeUp or safeDown are used, the unsafe methods cannot be used. We'll start by simply storing an ID, an email address, a password, the username, and some timestamp metadata indicating when our user was created and last updated.
Within our migration, we can write this as follows: We can either directly use the constants deined by the Schema class, or we can use the native migration methods, such as primaryKey , integer , string , and text. Using the migration methods is preferred because it permits us to add additional attributes to our column, such as the column size and length.
For a complete list of methods offered by the migration class, refer to the Yii2 guide at http: In the previous example, we outlined two methods: While Yii2 is smart enough to work with any ield names you specify, following this convention will make your code more readable and working with your databases less complicated.
While you don't have to explicitly follow this convention, following a convention can save you a lot of time in the future. Running migrations Running our migrations can be done through the yii command, as shown in the previous chapter: Using the sqlite command-line tool, we can explore our SQLite database: By running the.
The second table, user, shows the resulting schema that was created by Yii from our migration class. While database migrations are suited for most database changes, running them against large datasets may result in your database being unavailable to your application, resulting in downtime.
Make sure that before you run a database migration through Yii2, your application should be able to handle temporary downtime.
Yii 2 for Beginners
If even temporary downtime is not appropriate for your application, you may need to consider migrating your data to an updated schema in other ways. In this instance, we want to change our migrations without causing harm to their local instance; we can create new migrations that users of our code can apply in order to bring their applications up to date.
We may also want to make a few changes to other ields, such as our email ield, to prevent them from being NULL. We can do this by writing a new migration and altering the schema of the database itself. We'll start by creating a new migration: In the same vein, addColumn will add a new column with the speciied name and schema to our database, alterColumn will alter the schema for the named column, and createIndex will create a unique index on the email ield in our database, which will ensure that no two users will share the same email address.
If we try to run these migrations against our SQLite database, however, we would be presented with an error similar to the following, indicating that SQLite doesn't have support for these methods: Since we're using SQLite, however, we'd have to rewrite our initial migration command and notify users of our application about the change.
Consequently, if we need to query data within a migration, we will need to use Yii2's Query Builder to do this, which we'll cover later in this chapter. If our application has widespread adoption, it might be better to query for all of our users with Query Builder and store them temporarily in the memory or a temporary store if we have a large number of records. Then, after creating our new table schema for our users table, we could then reinsert them into our database using the insert method.
After updating our new migration, we can rerun our migration command. Take a look at the Yii2 documentation at http: Database access objects Yii database access objects, commonly referred to as DAO, provide a powerful object-oriented API to work with a relational database. Consequently, it is signiicantly more performant to work with DAO statements than it is to work with either Active Record or Query Builder. Since our db component is already properly conigured for SQLite, we'll use it moving forward.
With DAO, there are two general types of queries that we can run: Querying for data The irst way in which we can use DAO is to query for data. There are four main methods that are used to query for data: Using our user table as an example, we can query for all the users in our database by running the following command: In the event that no data is found, this method will return false: For instance, if we want to count the number of users in our database, we can use queryScalar to get the value: The inal method, queryColumn , is used to query a speciic column in our database.
For instance, if we want to know the email addresses of all the users in our database, we can use queryAll to fetch all that data, or we can use queryColumn , which would be signiicantly more eficient to use as it would query for less data: With our knowledge of these methods, as an exercise, let's go back to our previous migrations and rewrite them to preserve our users across our schema change: First, let's roll back our migrations to properly simulate the scenario: Next, let's seed our database with some test data: If we take a look at our database, we'll see that the initial schema and data is now in place.
The new code blocks have been highlighted for easy viewing: Now we can rerun our migration. If successful, we should see our original migration run and an insert call executed for each user in our database. Finally, we can query our SQLite database to preview the updated schema and see our updated users: Quoting table and column names When writing database-agnostic SQL queries, properly quoting ield names can be problematic. To avoid this problem, Yii2 provides the ability to automatically quote table and column names for you using the correct quoting rule for the speciic database in use.
To automatically quote a column name, simply enclose the column name in square brackets: To execute these commands, we can use the execute method in general: Yii2 also provides convenient wrappers for insert , update , and delete , which enables us to write commands without having to write raw SQL.
These methods properly escape and quote table and column names and bind parameters on your behalf. For instance, we can insert a new user into a database as follows: We can also delete a user in our database using the delete method: Parameter binding The number one rule when working with user-submitted data is to never trust user-submitted data.
Any data that passes through our databases and has come from an end user needs to be validated, sanitized, and properly bound to our statements before they are executed against our database. To help protect against SQL injection, Yii2 offers several different ways to bind parameters to our queries in a way that will ilter our injected SQL.
These three methods are bindValue , bindValues , and bindParam. The irst method, bindValue , is used to bind a single parameter to a token within our SQL statement. For example, we can rewrite the previous query as follows: Following the previous example, we can write the following to update multiple users without having to rewrite our query each time: This will protect you against future changes to your code.
Transactions When running multiple queries in a sequence, we often want to ensure that our database state remains consistent across these queries. Most modern databases support the use of transactions to accomplish this. In a transaction, changes are written to the database in such a way that they can be committed if everything went well or rolled back without consequence if any given query within the transaction failed.
In Yii2, this looks as follows: Yii's Query Builder allows us to write database-agnostic queries in a programmatic way. Consequently, queries written through the Query Builder are signiicantly more readable than their DAO counterparts. For example, we could simply query for all the users in our database in Query Builder using the following code: Query construction methods The basics of Query Builder involve the chaining of multiple query methods together.
These method names directly correspond with the SQL segment that they are named after. When working with Query Builder, the most common methods that you'll use will be the select , from , and where methods. For instance, the following queries are identical: If you choose to list the column names as a string, ensure that you do that consistently throughout your application.
In the following examples, we'll use the array format. The select method also supports column aliases and table preixes, as shown in the next example: For instance, if we want to retrieve the user's complete name as a single ield, we can execute the following query: For instance, if we want to list all the irst names of our user's database, we can execute the following query: The from method Our previous examples have already illustrated the basic usage of the from method.
The from method can also be used to specify a table alias, as shown in the following example: The where method The where method speciies the where segment of our SQL query and can be used either in a string format, hash format, or operator format. The string format The string format of the where method should always be chained with the addParams method in order to prevent SQL injection: Rather than passing a string as a parameter, we can instead pass an array of key values representing the column name and value.
For example, we can ind all the users in our database with the irst name of John who were in their 20s and who didn't have a listed pet name by running the following query: We will have to adjust our schema with a migration to add these ields to our database.
This would result in the following query: The operator format The last way to use the where method is to use the operator format. In general, the operator format takes the following format: As you can imagine, the where method can quickly become very bulky and complicated. Rather than using the operator, you may ind your code more readable by using the andWhere or orWhere methods to chain multiple conditions together: For example, to sort all of our users in our database by age, we can construct the following query: When properly used together, these two methods form the basics of paginating through results: Yii2 supports these methods via the groupBy and having methods.
After grouping our results with groupBy , we can then ilter our results with the having method, which behaves the same as the where method. The following example will only show the number of users in our dataset who are over a speciied age: Joins and unions can be performed through query builder using the join and union methods. The join method has the following method syntax: For example, suppose we had a posts and users table. We could join them as follows using the join method: The result would include all users joined with all the posts that they owned.
Joins can also be performed by type using the shortcut methods rightJoin , leftJoin , and innerJoin. Yii2 provides the following query methods to execute queries built with Query Builder.
Most of the times when working with Query Builder, we'll want to fetch all the records in our database.
Carefully consider using the all method if you have a large dataset, as the resulting query execution could take a long time to complete, and it could either hang or cause an error in your application. In other instances, it may be more beneicial just to fetch the irst row of a query.
To fetch the irst row, we can use the one method: To achieve this, we can use the exists method, which will return either true or false, indicating that data would be returned from the resulting query.
To fetch scalar values with query builder, we can use the scalar method. For instance, if we want to know how old the oldest user is in our database using the MAX SQL method, we can use the following code to return an integer representing their age: To fetch the irst row of our results, we can use the column method: Consequently, an array of all IDs in our database will be returned. It's important to remember when querying for data that you only query for the data you need.
If you need all data, you query for it in iterative way such as to limit the memory required for each query. To keep the memory consumption low and to prevent our application from hanging, we can use either the batch or each method.
By default, both methods will fetch rows from the database. To change the number of rows to be fetched, simply change the irst parameter of each method: Think of this method as a query appended with a limit and an offset parameter, which will restrict the number of returned rows. Each iteration of the batch query will contain multiple results. Like the batch method, the each method can be used to reduce memory consumption as well, but it will iterate over the query row-by-row instead, which means that each iteration of the method will result in a single instance of our data.
The beneit of using data providers and data widgets over queries built via Query Builder is that they provide an interface to automatically deal with sorting and pagination. Active data providers can also be populated through Query Builder, as shown in the following example: For more information on these data providers, check out the Yii2 guide at http: Once we have fetched our data with a data provider, we can pass the resulting data to a data widget.
Data widgets in Yii2 are reusable building blocks used within views to create complex interfaces to interact with data. In some instances, there may be sensitive data that we don't want to display on this page. Alternatively, there could simply be too much data to display in GridView. To restrict the number of ields to display in our GridView widget, we can use the columns attribute: More information on output data widgets can be found in the Yii2 guide at http: While some widgets, such as GridView, allow us to work with and display multiple rows, we can also use data providers and data widgets to display information for a single row.
With the DetailView widget, we can dynamically conigure a simple interface to display the information for a particular user in our database. The getModels method of our data provider splits our data provider into individual models that our DetailView widget can understand: This will be displayed on our screen: In addition to simply displaying results from a database, the DetailView widget also supports the custom formatting of certain rows.
More information on the formatter can be found at http: When working with large systems, we will split our database into a read-and-write master and a read-only slave of a set of slaves.
Typically, our applications are unaware of our database architecture, which can introduce problems when required to migrate from a new master. With Yii2, we can conigure our database connection to not only be aware of our master-slave database coniguration, but also intelligently handle slave unavailability.
In Yii2, we can conigure a single master and multiple slaves using the following database coniguration. This will result in all writes going to our declared master and all reads going to one of our declared slaves: When working with slaves, Yii will attempt to connect to slaves in the list until a slave responds and load balance queries against each of the available slaves. By setting PDO:: Alternatively, using the following coniguration, we can conigure our application to work with both multiple masters and multiple slaves.
When using multiple masters, Yii will execute writes against any available master and will load balance writes between the available masters: When working with a master-slave topology, we may want to issue a read query against one of our masters. To do that, we would need to explicitly tell Yii2 to run our query against our master rather than our slaves: If we need to issue a transaction against a slave, we will need to explicitly begin the transaction on a slave, as follows: By working with database access objects, we showed how we can execute raw SQL statements to run against our database and how we can use transactions to protect our database integrity.
We also illustrated the use of Query Builder, which can enable us to write database-agnostic queries in a programmatic way. We then discovered how we can use Query Builder to construct intelligent data providers, which are used to supply data to reusable data widgets. Finally, we learned how to conigure Yii2 to be aware of master-slave and multi-master database cluster conigurations and how to load balance between these connections.
In the next chapter, we discover the capstone of working with databases in Yii2—Active Record—which is a powerful tool used to work with our data and model our database structure. We'll also dive into Active Records relatives, basic models, and forms, and we'll learn how we can use a powerful tool called Gii to automate the construction of much of the code our modern applications will work with.
These classes enable us to abstract our data management code away from DAO and Query Builder and into an easy-to-use programmatic interface. In this chapter, we'll cover the use and implementation of Active Record and learn how to create data models and custom forms. We'll also cover how to conigure a powerful code generation tool called Gii to automate the creation of Active Record models and forms.
Coniguring Gii While Active Record models and forms can be generated by hand, in most cases, we'll want to automate the creation of this code. To achieve this, Yii2 provides a code generation tool called Gii, which can be executed both from the command line and from a web interface in order to create Active Record models that work with our database structure and forms that work with both our base models and Active Record models.
In Yii2, nearly every module is available as a separate Composer package, which can be installed from the command-line interface.
Consequently, we must use Composer to include Gii in our application. Since Gii is available as a composer package, we can include it in our application by running the following command from our command line: Typically, during our deployment process, we'll use the --no-dev lag to ensure that development packages are not deployed to our production environment.
With Gii installed, we now need to conigure it to work with both the Yii2 console and within our web browser. While this basic coniguration will properly load the Gii module, it doesn't follow our convention of being aware of our environment. For instance, if we went to production with this coniguration and deployed it with composer install --no- dev, as described earlier, our application would crash because Composer would not have installed the Gii module in our vendor folder. Define in.
Gii for console applications Unlike Yii1, Gii for Yii2 provides a new interface to work with Gii on the command line.
With Yii2, we can now generate the source code for Active Record models, forms, and even extensions all from our command-line interface. As we move through the rest of the chapter, we'll cover how to use Gii from the web interface as well as the console interface.
Active Record One of the most important tasks when building rich web applications is ensuring that we properly model and represent our data in code. From a simple blog site to an application as big as Twitter, data modeling and representation are vital to ensuring that our application is easy to work with and can grow as required. The Active Record pattern Named by Martin Fowler in his book Patterns of Enterprise Application Architecture, the Active Record pattern is an object-relational mapping ORM pattern that's used to represent database rows and columns within an object.
In the Active Record pattern, each database column is represented by a single Active Record class. Upon instantiation, that object then provides a simple interface to manage individual rows or a collection of rows within our code. New rows can be created, old ones can be deleted, and existing rows can be updated—all within a simple and consistent API. Active Record also enables us to programmatically reference and interact with related data, which is usually represented in our database by foreign key relations.
In this section, we'll cover how to create new Active Record classes, how to implement them within our code, and some common pitfalls of working with Active Record. Before we start working with Active Record, we irst need to create a couple of tables that we can work with. Included with the project resources for this chapter is a base migration that will create several new tables and populate them with some sample data: In Yii2, app is a predeined alias that points to our application base path.
If we want to, we can declare additional aliases, such as frontend and backend, to divide our application into different sections, which would enable us to create multiple Active Record instances in different namespaces. Finally, we need to implement the static method tableName within our class, which deines the table name our Active Record model will use.
Since our Active Record model will use the user table, we will deine this method as follows: Using Gii to create our Active Record classes has several advantages: From this page, we can generate Active Record classes based upon our database schema. As an example, let's create an active record instance for our user table: First, we need to populate the Table name ield with user, the name of the user table in our database.
As you type, Gii will try to show you possible database tables that match our text entry, which can be extremely beneicial when working with large databases. Next, we need to either press the Tab key on our keyboard, or focus our mouse onto the Model name ield, which should autopopulate the ield with User, which will be the name of the class that Gii will generate.
Then, we need to ensure that the Generate Relations checkbox is selected. This will automatically add the required code to our class in order to generate our model relations for the Post and Role classes, which we'll create in the next section. After checking this box, our form should be illed as follows: Then, we can click on the Preview button at the bottom of the page, which will enable us to preview the code that Gii will generate for us before we conirm the creation of our class.
In our Linux environment, this can be done by adding the www-data group to the folder and adjusting the permissions so that the user can write to it: Just ensure that you readjust the permissions to something more reasonable after using Gii to create the model. All of these ields are conigurable within the Gii web interface for us to change.
Using Gii's console interface As an alternative to Gii's web interface, Gii can generate Active Record classes from the command line.
When running Gii from the command line, we simply need to provide two attributes: This takes the following form: As shown in the previous code block, it has marked both the email and password attributes as required and the email ield as unique, and it has correctly identiied the appropriate data types for our name ields as well as timestamps.
Adding custom validators In addition to the many built-in core validators Yii2 has, we may need to write our own custom validators for our classes. Custom validators can either be written inline using anonymous functions, or they can be written as a separate method within our class.
For instance, suppose we only want to permit changes to our user information between certain core hours of our business. As an anonymous function, this can be written as follows: However, if we want to alter the error message for a certain property, we can do that by specifying the message parameter for a speciic validator.
For instance, we can adjust the error message for our unique validator by changing the last line of our validator to the following: As shown in the previous example, this takes the following form: This method will return an array of errors containing an array of error messages applicable for each attribute: While this can be done manually in our controller, it is typically executed before the save method is executed.
The validator method will return either true or false, indicating whether the validation was successful or not. Model attribute labels The next method that Gii automatically implements for us is the attributeLabels method. The attributesLabels method enables us to name our model attributes with more descriptive names that we can use as form labels. By default, Gii will automatically generate labels for us based upon our column names. Furthermore, by following the convention of using underscores in our column names in our user table, Gii has automatically created titleized and readable attribute labels for us: We'll cover the Yii:: Active Record relationships Assuming that we conigured our database schema properly with primary and foreign keys, Yii2 will also generate model relationships for us.
Our User model illustrates this for the Post and Role relationships: For instance, if we want to retrieve the name of the role for a user we are working with, we can simply execute the following: Check whether your relationships map to the correct classes and have the correct relationship types before executing your code.
Using multiple database connections with Active Record By default, all active record instances will use the db component to connect to our database.
In the instance where we have multiple databases connected to our application, we can conigure active record to work with an alternate database by deining the static method getDb within our Active Record class: To use a behavior with an Active Record class in Yii2, we simply need to specify that we want to use the behavior class at the top of our PHP ile and then add the behavior to the behaviors method of our model. Like most things in Yii2, this is completely conigurable.
Working with Active Record Now that we have learned what Gii automatically provides for us when creating new Active Record classes and what additional options we can add to our classes to enhance them, let's take a look at how we can use active record instances to perform basic create, read, update, and delete CRUD actions.
Both methods accept a scalar argument, an array of scalar arguments, or an array of associative pairs to query data: One way to get around this limitation is to convert our resulting data into an array format using the asArray method: While the asArray method can be used to increase the performance of large queries, it has several downsides.
The data returned will not be an instance of Active Record, and thus, it will not have any of the methods or helpful attributes associated with it. Moreover, since data is being returned directly from PDO, the data will not be typecast automatically and will be returned as a string instead. Data access When using Active Record, each row from our database query will generate a single Active Record instance. The column values from our Active Record instance can be accessed via the model attributes for that Active Record instance: For instance, to retrieve the author's name from a given post, we can run the following code: If having Active Record attributes with underscores doesn't match your coding style, you should rename your column names.
Our data can also be manipulated by creating a custom getter and setter method within our Active Record class. For instance, if we want to display the user's complete name without changing our database schema, we can add the following method to our User Active Record class: If we retrieved our user information from the database again, we would see that the results were stored: Typically when using the load method, we'll provide data from a form submission, which we'll cover later in this chapter.Gii for console applications Unlike Yii1, Gii for Yii2 provides a new interface to work with Gii on the command line.
With Yii2, we can work directly with Node and Bower packages. Ok, so the easy part is to figure out that utilizing a framework will help you develop a more organized and robust project, but now comes the hard part.
This is advantageous as we can version lock our build tools to our application. Reduces time spent on plumbing tasks such as form validation and security.
Another key aspect of the database is that it allows us to structure the data in such a way as to connect things like the users address and their username as if they were one record, but hold them in separate tables as separate records. The Gii command The next set of commands in our toolbox is the Gii command. It checks if the server is running the right version of PHP, if appropriate PHP extensions have been loaded, and if php.
For example, we can ind all the users in our database with the irst name of John who were in their 20s and who didn't have a listed pet name by running the following query: Additional coniguration options In addition to the basic db component options listed previously, Yii2 also provides several additional options that can be used to either enhance the performance of your application or deal with a known issue within the native PHP drivers.