Commit 5b8cf206 by Qiang Xue

guide wip [skip ci]

parent a6203423
......@@ -23,6 +23,7 @@ Getting Started
* [Starting with Advanced App](start-advanced.md) - Best for developing an enterprise application by a team
* [Starting from Scratch](start-scratch.md) - Learning more in-depth details of creating a Yii application step-by-step
Basic Concepts
--------------
......@@ -30,11 +31,11 @@ Basic Concepts
* [Events](basic-events.md)
* [Behaviors](basic-behaviors.md)
* [Object Configurations](basic-configs.md)
* **TBD** [Class Autoloading](basic-autoloading.md)
* **TBD** [Path Aliases](basic-alias.md)
* [Class Autoloading](basic-autoloading.md)
* [Path Aliases](basic-alias.md)
* **TBD** [Extensions](basic-extensions.md)
* [Service Locator](basic-service-locator.md)
* **TBD** [Dependency Injection Container](basic-di-container.md)
* [Dependency Injection Container](basic-di-container.md)
Basic Structure
......@@ -63,6 +64,19 @@ Handling Requests
* **TBD** [Filtering](runtime-filtering.md)
Working with Databases
----------------------
* [Data Access Objects](db-dao.md) - Connecting to a database, basic queries, transactions and schema manipulation
* [Query Builder](db-query-builder.md) - Querying the database using a simple abstraction layer
* [Active Record](db-active-record.md) - The active record ORM, retrieving and manipulating records and defining relations
* [Migrations](db-migrations.md) - Version control your databases in a team development environment
* **TBD** [Sphinx](db-sphinx.md)
* **TBD** [Redis](db-redis.md)
* **TBD** [MongoDB](db-mongodb.md)
* **TBD** [ElasticSearch](db-elastic-search.md)
Collecting Inputs
-----------------
......@@ -83,19 +97,6 @@ Presenting Data
* [Managing Assets](output-assets.md)
Working with Database
---------------------
* [Data Access Objects](db-dao.md) - Connecting to a database, basic queries, transactions and schema manipulation
* [Query Builder](db-query-builder.md) - Querying the database using a simple abstraction layer
* [Active Record](db-active-record.md) - The active record ORM, retrieving and manipulating records and defining relations
* [Migrations](db-migrations.md)
* **TBD** [Sphinx](db-sphinx.md)
* **TBD** [Redis](db-redis.md)
* **TBD** [MongoDB](db-mongodb.md)
* **TBD** [ElasticSearch](db-elastic-search.md)
Security
--------
......@@ -130,6 +131,14 @@ RESTful Web Services
* **TBD** [Testing](rest-testing.md)
Development Tools
-----------------
* [Debug Toolbar and Debugger](tool-debugger.md)
* [Generating Code using Gii](tool-gii.md)
* **TBD** [Generating API Documentation](tool-api-doc.md)
Testing
-------
......@@ -151,14 +160,6 @@ Extending Yii
* [Using Composer](extend-using-composer.md)
Development Tools
-----------------
* [Debug Toolbar and Debugger](tool-debugger.md)
* [Generating Code using Gii](tool-gii.md)
* **TBD** [Generating API Documentation](tool-api-doc.md)
Special Topics
--------------
......@@ -192,6 +193,7 @@ Widgets
Helpers
-------
* [Overview](helper-overview.md)
* **TBD** [ArrayHelper](helper-array.md)
* **TBD** [Html](helper-html.md)
* **TBD** [Url](helper-url.md)
......
Path Aliases
============
> Note: This chapter is under development.
Yii 2.0 expands the usage of path aliases to both file/directory paths and URLs. An alias
must start with an `@` symbol so that it can be differentiated from file/directory paths and URLs.
For example, the alias `@yii` refers to the Yii installation directory while `@web` contains the base URL for the currently running web application. Path aliases are supported in most places in the Yii core code. For example, `FileCache::cachePath` can accept both a path alias and a normal directory path.
Path aliases are also closely related to class namespaces. It is recommended that a path
alias should be defined for each root namespace so that Yii's class autoloader can be used without
any further configuration. For example, because `@yii` refers to the Yii installation directory,
a class like `yii\web\Request` can be autoloaded by Yii. If you use a third party library
such as Zend Framework, you may define a path alias `@Zend` which refers to its installation
directory and Yii will be able to autoload any class in this library.
The following aliases are predefined by the core framework:
- `@yii` - framework directory.
- `@app` - base path of currently running application.
- `@runtime` - runtime directory.
- `@vendor` - Composer vendor directory.
- `@webroot` - web root directory of currently running web application.
- `@web` - base URL of currently running web application.
Autoloading
===========
> Note: This chapter is under development.
All classes, interfaces and traits are loaded automatically at the moment they are used. There's no need to use `include` or `require`. It is true for Composer-loaded packages as well as Yii extensions.
Yii's autoloader works according to [PSR-4](https://github.com/php-fig/fig-standards/blob/master/proposed/psr-4-autoloader/psr-4-autoloader.md).
That means namespaces, classes, interfaces and traits must correspond to file system paths and file names accordinly, except for root namespace paths that are defined by an alias.
For example, if the standard alias `@app` refers to `/var/www/example.com/` then `\app\models\User` will be loaded from `/var/www/example.com/models/User.php`.
Custom aliases may be added using the following code:
```php
Yii::setAlias('@shared', realpath('~/src/shared'));
```
Additional autoloaders may be registered using PHP's standard `spl_autoload_register`.
Configuration
=============
> Note: This chapter is under development.
Object Configuration
--------------------
The [[yii\base\Object|Object]] class introduces a uniform way of configuring objects. Any descendant class
of [[yii\base\Object|Object]] should declare its constructor (if needed) in the following way so that
it can be properly configured:
```php
class MyClass extends \yii\base\Object
{
public function __construct($param1, $param2, $config = [])
{
// ... initialization before configuration is applied
parent::__construct($config);
}
public function init()
{
parent::init();
// ... initialization after configuration is applied
}
}
```
In the above example, the last parameter of the constructor must take a configuration array
which contains name-value pairs that will be used to initialize the object's properties at the end of the constructor.
You can override the `init()` method to do initialization work after the configuration is applied.
By following this convention, you will be able to create and configure new objects
using a configuration array like the following:
```php
$object = Yii::createObject([
'class' => 'MyClass',
'property1' => 'abc',
'property2' => 'cde',
], [$param1, $param2]);
```
Yii applications rely upon components to perform most of the common tasks, such as connecting to a database, routing browser
requests, and handling sessions. How these stock components behave can be adjusted by *configuring* your Yii application.
The majority of components have sensible default settings, so it's unlikely that you'll do a lot of configuration. Still, there are some mandatory configuration settings that you will have to establish, such as the database connection.
......
Dependency Injection Container
==============================
Both service locator and dependency injection are popular design patterns that allow building software
in a loosely-coupled fashion. Yii uses service locator and dependency injection extensively,
even though you may not be aware of them. In this tutorial, we will explore their implementation
and support to help you write code more consciously. We also highly recommend you to read
[Martin's article](http://martinfowler.com/articles/injection.html) to get a deeper understanding of
service locator and dependency injection.
A dependency injection (DI) container is an object that knows how to instantiate and configure objects and
all their dependent objects. [Martin's article](http://martinfowler.com/articles/injection.html) has well
explained why DI container is useful. Here we will mainly explain the usage of the DI container provided by Yii.
Yii provides the DI container feature through the class [[yii\di\Container]]. It supports the following kinds of
dependency injection:
* Constructor injection;
* Setter injection;
* PHP callable injection.
### Registering Dependencies
You can use [[yii\di\Container::set()]] to register dependencies. The registration requires a dependency name
as well as a dependency definition. The name can be a class name, an interface name, or an alias name;
and the definition can be a class name, a configuration array, or a PHP callable.
```php
$container = new \yii\di\Container;
// register a class name as is. This can be skipped.
$container->set('yii\db\Connection');
// register an interface
// When a class depends on the interface, the corresponding class
// will be instantiated as the dependent object
$container->set('yii\mail\MailInterface', 'yii\swiftmailer\Mailer');
// register an alias name. You can use $container->get('foo')
// to create an instance of Connection
$container->set('foo', 'yii\db\Connection');
// register a class with configuration. The configuration
// will be applied when the class is instantiated by get()
$container->set('yii\db\Connection', [
'dsn' => 'mysql:host=127.0.0.1;dbname=demo',
'username' => 'root',
'password' => '',
'charset' => 'utf8',
]);
// register an alias name with class configuration
// In this case, a "class" element is required to specify the class
$container->set('db', [
'class' => 'yii\db\Connection',
'dsn' => 'mysql:host=127.0.0.1;dbname=demo',
'username' => 'root',
'password' => '',
'charset' => 'utf8',
]);
// register a PHP callable
// The callable will be executed when $container->get('db') is called
$container->set('db', function ($container, $params, $config) {
return new \yii\db\Connection($config);
});
```
> Tip: If a dependency name is the same as the corresponding dependency definition, you do not
need to register it with the DI container.
A dependency registered via `set()` will generate an instance each time the dependency is needed.
You can use [[yii\di\Container::setSingleton()]] to register a dependency that only generates
a single instance:
```php
$container->setSingleton('yii\db\Connection', [
'dsn' => 'mysql:host=127.0.0.1;dbname=demo',
'username' => 'root',
'password' => '',
'charset' => 'utf8',
]);
```
### Resolving Dependencies
Once you have registered dependencies, you can use the DI container to create new objects,
and the container will automatically resolve dependencies by instantiating them and injecting
them into the newly created objects. The dependency resolution is recursive, meaning that
if a dependency has other dependencies, those dependencies will also be resolved automatically.
You use [[yii\di\Container::get()]] to create new objects. The method takes a class name or
a dependency name (class name, interface name or alias name) that you previously registered
via `set()` or `setSingleton()`. You may optionally provide a list of class constructor parameters
and a list of name-value pairs to configure the newly created object. For example,
```php
// equivalent to: $map = new \app\components\GoogleMap($apiKey);
$map = $container->get('app\components\GoogleMap', [$apiKey]);
// "db" is a previously registered alias name
$db = $container->get('db');
```
Behind the scene, the DI container does much more work than just creating a new object.
The container will inspect the class constructor to find out dependent class or interface names
and then automatically resolve those dependencies recursively.
The following code shows a more sophisticated example. The `UserLister` class depends on an object implementing
the `UserFinderInterface` interface; the `UserFinder` class implements this interface and depends on
a `Connection` object. All these dependencies are declared through type hinting of the class constructor parameters.
With property dependency registration, the DI container is able to resolve these dependencies automatically
and creates a new `UserLister` instance with a simple call of `get('userLister')`.
```php
namespace app\models;
use yii\base\Object;
use yii\db\Connection;
use yii\di\Container;
interface UserFinderInterface
{
function findUser();
}
class UserFinder extends Object implements UserFinderInterface
{
public $db;
public function __construct(Connection $db, $config = [])
{
$this->db = $db;
parent::__construct($config);
}
public function findUser()
{
}
}
class UserLister extends Object
{
public $finder;
public function __construct(UserFinderInterface $finder, $config = [])
{
$this->finder = $finder;
parent::__construct($config);
}
}
$container = new Container;
$container->set('yii\db\Connection', [
'dsn' => '...',
]);
$container->set('app\models\UserFinderInterface', [
'class' => 'app\models\UserFinder',
]);
$container->set('userLister', 'app\models\UserLister');
$lister = $container->get('userLister');
// which is equivalent to:
$db = new \yii\db\Connection(['dsn' => '...']);
$finder = new UserFinder($db);
$lister = new UserLister($finder);
```
### Practical Usage
Yii creates a DI container when you include the `yii.php` file in your application's entry script.
The DI container is accessible via [[Yii::$container]]. When you call [[Yii::createObject()]], the method
will actually call the container's [[yii\di\Container::get()|get()]] method to create a new object.
As aforementioned, the DI container will automatically resolve the dependencies (if any) and inject them
into the newly created object. Because Yii uses [[Yii::createObject()]] in most of its core code to create
new objects, this means you can customize the objects globally by dealing with [[Yii::$container]].
For example, you can customize globally the default number of pagination buttons of [[yii\widgets\LinkPager]]:
```php
\Yii::$container->set('yii\widgets\LinkPager', ['maxButtonCount' => 5]);
```
Now if you use the widget in a view with the following code, the `maxButtonCount` property will be initialized
as 5 instead of 10 as defined in the class.
```php
echo \yii\widgets\LinkPager::widget();
```
You can still override the value set via DI container:
```php
echo \yii\widgets\LinkPager::widget(['maxButtonCount' => 20]);
```
Another example is to take advantage of the automatic constructor injection of the DI container.
Assume your controller class depends on some other objects, such as a hotel booking service. You
can declare the dependency through a constructor parameter and let the DI container to resolve it for you.
```php
namespace app\controllers;
use yii\web\Controller;
use app\components\BookingInterface;
class HotelController extends Controller
{
protected $bookingService;
public function __construct($id, $module, BookingInterface $bookingService, $config = [])
{
$this->bookingService = $bookingService;
parent::__construct($id, $module, $config);
}
}
```
If you access this controller from browser, you will see an error complaining the `BookingInterface`
cannot be instantiated. This is because you need to tell the DI container how to deal with this dependency:
```php
\Yii::$container->set('app\components\BookingInterface', 'app\components\BookingService');
```
Now if you access the controller again, an instance of `app\components\BookingService` will be
created and injected as the 3rd parameter to the controller's constructor.
### When to Register Dependencies
Because dependencies are needed when new objects are being created, their registration should be done
as early as possible. The followings are the recommended practices:
* If you are the developer of an application, you can register dependencies in your
application's entry script or in a script that is included by the entry script.
* If you are the developer of a redistributable extension, you can register dependencies
in the bootstrap class of the extension.
Basic concepts of Yii
=====================
Object Properties
=================
In PHP, class member variables are also called *properties*. They are part of a class definition and are used
to represent the state of a class instance. In practice, you may often want to do some special handling when
a property is being read or modified. For example, you may want to trim a string when it is being assigned
to a `label` property. You could use the following code to achieve this task:
Component and Object
--------------------
Classes of the Yii framework usually extend from one of the two base classes [[yii\base\Object]] or [[yii\base\Component]].
These classes provide useful features that are added automatically to all classes extending from them.
```php
$object->label = trim($label);
```
The [[yii\base\Object|Object]] class provides the [configuration and property feature](../api/base/Object.md).
The [[yii\base\Component|Component]] class extends from [[yii\base\Object|Object]] and adds
[event handling](events.md) and [behaviors](behaviors.md).
The drawback of the above code is that you have to call `trim()` everywhere whenever you modify the `label`
property. And if in future, the `label` property has a new requirement, such as the first letter must be turned
into upper case, you would have to modify all those places - a practice you want to avoid as much as possible.
[[yii\base\Object|Object]] is usually used for classes that represent basic data structures while
[[yii\base\Component|Component]] is used for application components and other classes that implement higher logic.
To solve this problem, Yii introduces the support for defining properties based on *getter* and *setter* class methods.
**A class must extend from [[yii\base\Object]] or its child class if it wants to get this support.**
A getter method is a method whose name starts with the word `get`, while a setter method starts with `set`.
The name after the `get` or `set` prefix defines the name of a property. For example, a getter `getLabel()` and/or
a setter `setLabel()` defines a property named `label`, as shown in the following code:
Object Configuration
--------------------
```php
namespace app\components;
The [[yii\base\Object|Object]] class introduces a uniform way of configuring objects. Any descendant class
of [[yii\base\Object|Object]] should declare its constructor (if needed) in the following way so that
it can be properly configured:
use yii\base\Object;
```php
class MyClass extends \yii\base\Object
class Foo extend Object
{
public function __construct($param1, $param2, $config = [])
{
// ... initialization before configuration is applied
private $_label;
parent::__construct($config);
public function getLabel()
{
return $this->_label;
}
public function init()
public function setLabel($value)
{
parent::init();
// ... initialization after configuration is applied
$this->_label = trim($value);
}
}
```
In the above example, the last parameter of the constructor must take a configuration array
which contains name-value pairs that will be used to initialize the object's properties at the end of the constructor.
You can override the `init()` method to do initialization work after the configuration is applied.
By following this convention, you will be able to create and configure new objects
using a configuration array like the following:
Properties defined by getters/setters can be used like class member variables. The main difference is that
when such a property is being read, the corresponding getter method will be called; and when the property is
being assigned, the corresponding setter method will be called. For example,
```php
$object = Yii::createObject([
'class' => 'MyClass',
'property1' => 'abc',
'property2' => 'cde',
], [$param1, $param2]);
```
Path Aliases
------------
// equivalent to $label = $object->getLabel();
$label = $object->label;
Yii 2.0 expands the usage of path aliases to both file/directory paths and URLs. An alias
must start with an `@` symbol so that it can be differentiated from file/directory paths and URLs.
For example, the alias `@yii` refers to the Yii installation directory while `@web` contains the base URL for the currently running web application. Path aliases are supported in most places in the Yii core code. For example, `FileCache::cachePath` can accept both a path alias and a normal directory path.
Path aliases are also closely related to class namespaces. It is recommended that a path
alias should be defined for each root namespace so that Yii's class autoloader can be used without
any further configuration. For example, because `@yii` refers to the Yii installation directory,
a class like `yii\web\Request` can be autoloaded by Yii. If you use a third party library
such as Zend Framework, you may define a path alias `@Zend` which refers to its installation
directory and Yii will be able to autoload any class in this library.
The following aliases are predefined by the core framework:
- `@yii` - framework directory.
- `@app` - base path of currently running application.
- `@runtime` - runtime directory.
- `@vendor` - Composer vendor directory.
- `@webroot` - web root directory of currently running web application.
- `@web` - base URL of currently running web application.
Autoloading
-----------
All classes, interfaces and traits are loaded automatically at the moment they are used. There's no need to use `include` or `require`. It is true for Composer-loaded packages as well as Yii extensions.
Yii's autoloader works according to [PSR-4](https://github.com/php-fig/fig-standards/blob/master/proposed/psr-4-autoloader/psr-4-autoloader.md).
That means namespaces, classes, interfaces and traits must correspond to file system paths and file names accordinly, except for root namespace paths that are defined by an alias.
For example, if the standard alias `@app` refers to `/var/www/example.com/` then `\app\models\User` will be loaded from `/var/www/example.com/models/User.php`.
Custom aliases may be added using the following code:
```php
Yii::setAlias('@shared', realpath('~/src/shared'));
// equivalent to $object->setLabel('abc');
$object->label = 'abc';
```
Additional autoloaders may be registered using PHP's standard `spl_autoload_register`.
A property defined by a getter without a setter is read only. Trying to assign a value to such a property will cause
an [[yii\base\InvalidCallException|InvalidCallException]]. Similarly, a property defined by a setter without a getter
is write only, and trying to read such a property will also cause an exception. It is not common to have write-only
properties.
Helper classes
--------------
Back to the problem we described at the beginning, the `trim()` function is now called within the setter `setLabel()`.
If a new requirement comes that the first letter of the label should be turned into upper case, we only need to
modify the `setLabel()` method without touching other code.
Helper classes typically contain static methods only and are used as follows:
```php
use \yii\helpers\Html;
echo Html::encode('Test > test');
```
There are some special rules or limitations of the properties defined based on getters and setters.
First, the names of such properties are *case-insensitive*. This is because PHP method names are case-insensitive.
Second, the properties do not support visibility. It makes no difference for the visibility of a property
if the defining getter or setter method is public, protected or private. Third, the properties can only
be defined by *non-static* getters and/or setters. Static methods do not count.
There are several classes provided by framework:
- ArrayHelper
- Console
- FileHelper
- Html
- HtmlPurifier
- Image
- Inflector
- Json
- Markdown
- Security
- StringHelper
- Url
- VarDumper
Service Locator and Dependency Injection
========================================
Service Locator
===============
> Note: This chapter needs cleanup.
Both service locator and dependency injection are popular design patterns that allow building software
in a loosely-coupled fashion. Yii uses service locator and dependency injection extensively,
......@@ -8,10 +10,6 @@ and support to help you write code more consciously. We also highly recommend yo
[Martin's article](http://martinfowler.com/articles/injection.html) to get a deeper understanding of
service locator and dependency injection.
Service Locator
---------------
A service locator is an object that knows how to provide all sorts of services (or components) that an application
might need. Within a service locator, each component has only a single instance which is uniquely identified by an ID.
You use the ID to retrieve a component from the service locator. In Yii, a service locator is simply an instance
......@@ -87,243 +85,3 @@ return [
],
];
```
Dependency Injection
--------------------
A dependency injection (DI) container is an object that knows how to instantiate and configure objects and
all their dependent objects. [Martin's article](http://martinfowler.com/articles/injection.html) has well
explained why DI container is useful. Here we will mainly explain the usage of the DI container provided by Yii.
Yii provides the DI container feature through the class [[yii\di\Container]]. It supports the following kinds of
dependency injection:
* Constructor injection;
* Setter injection;
* PHP callable injection.
### Registering Dependencies
You can use [[yii\di\Container::set()]] to register dependencies. The registration requires a dependency name
as well as a dependency definition. The name can be a class name, an interface name, or an alias name;
and the definition can be a class name, a configuration array, or a PHP callable.
```php
$container = new \yii\di\Container;
// register a class name as is. This can be skipped.
$container->set('yii\db\Connection');
// register an interface
// When a class depends on the interface, the corresponding class
// will be instantiated as the dependent object
$container->set('yii\mail\MailInterface', 'yii\swiftmailer\Mailer');
// register an alias name. You can use $container->get('foo')
// to create an instance of Connection
$container->set('foo', 'yii\db\Connection');
// register a class with configuration. The configuration
// will be applied when the class is instantiated by get()
$container->set('yii\db\Connection', [
'dsn' => 'mysql:host=127.0.0.1;dbname=demo',
'username' => 'root',
'password' => '',
'charset' => 'utf8',
]);
// register an alias name with class configuration
// In this case, a "class" element is required to specify the class
$container->set('db', [
'class' => 'yii\db\Connection',
'dsn' => 'mysql:host=127.0.0.1;dbname=demo',
'username' => 'root',
'password' => '',
'charset' => 'utf8',
]);
// register a PHP callable
// The callable will be executed when $container->get('db') is called
$container->set('db', function ($container, $params, $config) {
return new \yii\db\Connection($config);
});
```
> Tip: If a dependency name is the same as the corresponding dependency definition, you do not
need to register it with the DI container.
A dependency registered via `set()` will generate an instance each time the dependency is needed.
You can use [[yii\di\Container::setSingleton()]] to register a dependency that only generates
a single instance:
```php
$container->setSingleton('yii\db\Connection', [
'dsn' => 'mysql:host=127.0.0.1;dbname=demo',
'username' => 'root',
'password' => '',
'charset' => 'utf8',
]);
```
### Resolving Dependencies
Once you have registered dependencies, you can use the DI container to create new objects,
and the container will automatically resolve dependencies by instantiating them and injecting
them into the newly created objects. The dependency resolution is recursive, meaning that
if a dependency has other dependencies, those dependencies will also be resolved automatically.
You use [[yii\di\Container::get()]] to create new objects. The method takes a class name or
a dependency name (class name, interface name or alias name) that you previously registered
via `set()` or `setSingleton()`. You may optionally provide a list of class constructor parameters
and a list of name-value pairs to configure the newly created object. For example,
```php
// equivalent to: $map = new \app\components\GoogleMap($apiKey);
$map = $container->get('app\components\GoogleMap', [$apiKey]);
// "db" is a previously registered alias name
$db = $container->get('db');
```
Behind the scene, the DI container does much more work than just creating a new object.
The container will inspect the class constructor to find out dependent class or interface names
and then automatically resolve those dependencies recursively.
The following code shows a more sophisticated example. The `UserLister` class depends on an object implementing
the `UserFinderInterface` interface; the `UserFinder` class implements this interface and depends on
a `Connection` object. All these dependencies are declared through type hinting of the class constructor parameters.
With property dependency registration, the DI container is able to resolve these dependencies automatically
and creates a new `UserLister` instance with a simple call of `get('userLister')`.
```php
namespace app\models;
use yii\base\Object;
use yii\db\Connection;
use yii\di\Container;
interface UserFinderInterface
{
function findUser();
}
class UserFinder extends Object implements UserFinderInterface
{
public $db;
public function __construct(Connection $db, $config = [])
{
$this->db = $db;
parent::__construct($config);
}
public function findUser()
{
}
}
class UserLister extends Object
{
public $finder;
public function __construct(UserFinderInterface $finder, $config = [])
{
$this->finder = $finder;
parent::__construct($config);
}
}
$container = new Container;
$container->set('yii\db\Connection', [
'dsn' => '...',
]);
$container->set('app\models\UserFinderInterface', [
'class' => 'app\models\UserFinder',
]);
$container->set('userLister', 'app\models\UserLister');
$lister = $container->get('userLister');
// which is equivalent to:
$db = new \yii\db\Connection(['dsn' => '...']);
$finder = new UserFinder($db);
$lister = new UserLister($finder);
```
### Practical Usage
Yii creates a DI container when you include the `yii.php` file in your application's entry script.
The DI container is accessible via [[Yii::$container]]. When you call [[Yii::createObject()]], the method
will actually call the container's [[yii\di\Container::get()|get()]] method to create a new object.
As aforementioned, the DI container will automatically resolve the dependencies (if any) and inject them
into the newly created object. Because Yii uses [[Yii::createObject()]] in most of its core code to create
new objects, this means you can customize the objects globally by dealing with [[Yii::$container]].
For example, you can customize globally the default number of pagination buttons of [[yii\widgets\LinkPager]]:
```php
\Yii::$container->set('yii\widgets\LinkPager', ['maxButtonCount' => 5]);
```
Now if you use the widget in a view with the following code, the `maxButtonCount` property will be initialized
as 5 instead of 10 as defined in the class.
```php
echo \yii\widgets\LinkPager::widget();
```
You can still override the value set via DI container:
```php
echo \yii\widgets\LinkPager::widget(['maxButtonCount' => 20]);
```
Another example is to take advantage of the automatic constructor injection of the DI container.
Assume your controller class depends on some other objects, such as a hotel booking service. You
can declare the dependency through a constructor parameter and let the DI container to resolve it for you.
```php
namespace app\controllers;
use yii\web\Controller;
use app\components\BookingInterface;
class HotelController extends Controller
{
protected $bookingService;
public function __construct($id, $module, BookingInterface $bookingService, $config = [])
{
$this->bookingService = $bookingService;
parent::__construct($id, $module, $config);
}
}
```
If you access this controller from browser, you will see an error complaining the `BookingInterface`
cannot be instantiated. This is because you need to tell the DI container how to deal with this dependency:
```php
\Yii::$container->set('app\components\BookingInterface', 'app\components\BookingService');
```
Now if you access the controller again, an instance of `app\components\BookingService` will be
created and injected as the 3rd parameter to the controller's constructor.
### When to Register Dependencies
Because dependencies are needed when new objects are being created, their registration should be done
as early as possible. The followings are the recommended practices:
* If you are the developer of an application, you can register dependencies in your
application's entry script or in a script that is included by the entry script.
* If you are the developer of a redistributable extension, you can register dependencies
in the bootstrap class of the extension.
Bootstrap widgets
Bootstrap Widgets
=================
> Note: This chapter is under development.
Out of the box, Yii includes support for the [Bootstrap 3](http://getbootstrap.com/) markup and components framework (also known as "Twitter Bootstrap"). Bootstrap is an excellent, responsive framework that can greatly speed up the client-side of your development process.
The core of Bootstrap is represented by two parts:
......
Caching
=======
> Note: This chapter is under development.
Caching is a cheap and effective way to improve the performance of a web application. By storing relatively
static data in cache and serving it from cache when requested, the application saves the time required to generate the data from scratch. Caching is one of the best ways to improve the performance of your application, almost mandatory on any large-scale site.
......
Active Record
=============
> Note: This chapter is under development.
[Active Record](http://en.wikipedia.org/wiki/Active_record_pattern) provides an object-oriented interface
for accessing data stored in a database. An Active Record class is associated with a database table,
an Active Record instance corresponds to a row of that table, and an attribute of an Active Record
......
Database basics
===============
> Note: This chapter is under development.
Yii has a database access layer built on top of PHP's [PDO](http://www.php.net/manual/en/book.pdo.php). It provides
uniform API and solves some inconsistencies between different DBMS. By default Yii supports the following DBMS:
......
Database Migration
==================
> Note: This chapter is under development.
Like source code, the structure of a database evolves as a database-driven application is developed and maintained. For example, during development, a new table may be added; Or, after the application goes live, it may be discovered that an additional index is required. It is important to keep track of these structural database changes (called **migration**), just as changes to the source code is tracked using version control. If the source code and the database become out of sync, bugs will occur, or the whole application might break. For this reason, Yii provides a database migration
tool that can keep track of database migration history, apply new migrations, or revert existing ones.
......
Query Builder and Query
=======================
> Note: This chapter is under development.
Yii provides a basic database access layer as described in the [Database basics](database-basics.md) section.
The database access layer provides a low-level way to interact with the database. While useful in some situations,
it can be tedious and error-prone to write raw SQLs. An alternative approach is to use the Query Builder.
......
Extending Yii
=============
> Note: This chapter is under development.
The Yii framework was designed to be easily extendable. Additional features can be added to your project and then reused, either by yourself on other projects or by sharing your work as a formal Yii extension.
Code style
......
Helper Classes
==============
> Note: This chapter is under development.
Yii provides many classes that help simplify common coding tasks, such as string or array manipulations,
HTML code generation, and so forth. These helper classes are organized under the `yii\helpers` namespace and
are all static classes (meaning they contain only static properties and methods and should not be instantiated).
......
Composer
========
> Note: This chapter is under development.
Yii2 uses Composer as its dependency management tool. Composer is a PHP utility that can automatically handle the installation of needed libraries and
extensions, thereby keeping those third-party resources up to date while absolving you of the need to manually manage the project's dependencies.
......
Using 3rd-Party Libraries
=========================
> Note: This chapter is under development.
Yii is carefully designed so that third-party libraries can be
easily integrated to further extend Yii's functionalities.
......
Helpers
=======
> Note: This chapter is under development.
Helper classes typically contain static methods only and are used as follows:
```php
use \yii\helpers\Html;
echo Html::encode('Test > test');
```
There are several classes provided by framework:
- ArrayHelper
- Console
- FileHelper
- Html
- HtmlPurifier
- Image
- Inflector
- Json
- Markdown
- Security
- StringHelper
- Url
- VarDumper
Working with forms
==================
> Note: This chapter is under development.
The primary way of using forms in Yii is through [[yii\widgets\ActiveForm]]. This approach should be preferred when
the form is based upon a model. Additionally, there are some useful methods in [[yii\helpers\Html]] that are typically
used for adding buttons and help text to any form.
......
Model validation reference
==========================
> Note: This chapter is under development.
As a model both represents data and defines the business rules to which that data must adhere, comprehending data validation is key to using Yii. In order to learn model validation basics, please refer to [Model, Validation subsection](model.md#Validation).
This guide describes all of Yii's validators and their parameters.
......
Managing assets
===============
> Note: This chapter is under development.
An asset in Yii is a file that is included into the page. It could be CSS, JavaScript or
any other file. The framework provides many ways to work with assets from basics such as adding `<script src="...">` tags
for a file which is covered by the [View section](view.md), to advanced usage such as publishing files that are not
......
Data providers
==============
> Note: This chapter is under development.
Data provider abstracts data set via [[yii\data\DataProviderInterface]] and handles pagination and sorting.
It can be used by [grids](data-grid.md), [lists and other data widgets](data-widgets.md).
......
Data widgets
============
> Note: This chapter is under development.
ListView
--------
......
Implementing RESTful Web Service APIs
=====================================
> Note: This chapter is under development.
Yii provides a whole set of tools to greatly simplify the task of implementing RESTful Web Service APIs.
In particular, Yii provides support for the following aspects regarding RESTful APIs:
......
URL Management
==============
> Note: This chapter is under development.
The concept of URL management in Yii is fairly simple. URL management is based on the premise that the application uses
internal routes and parameters everywhere. The framework itself will then translate routes into URLs, and vice versa, according to the URL manager's configuration. This approach allows you to change site-wide URLs merely by
editing a single configuration file, without ever touching the application code.
......
Authentication
==============
> Note: This chapter is under development.
Authentication is the act of verifying who a user is, and is the basis of the login process. Typically, authentication uses the combination of an identifier--a username or email address--and a password. The user submits these values through a form, and the application then compares the submitted information against that previously stored (e.g., upon registration).
In Yii, this entire process is performed semi-automatically, leaving the developer to merely implement [[yii\web\IdentityInterface]], the most important class in the authentication system. Typically, implementation of `IdentityInterface` is accomplished using the `User` model.
......
Authorization
=============
> Note: This chapter is under development.
Authorization is the process of verifying that a user has enough permission to do something. Yii provides two authorization
methods: Access Control Filter (ACF) and Role-Based Access Control (RBAC).
......
Security
========
> Note: This chapter is under development.
Good security is vital to the health and success of any application. Unfortunately, many developers cut corners when it comes to security, either due to a lack of understanding or because implementation is too much of a hurdle. To make your Yii powered application as secure as possible, Yii has included several excellent and easy to use security features.
......
Advanced application template
=============================
> Note: This chapter is under development.
This template is for large projects developed in teams where the backend is divided from the frontend, application is deployed
to multiple servers etc. This application template also goes a bit further regarding features and provides essential
database, signup and password restore out of the box.
......
Basic application template
==========================
> Note: This chapter is under development.
The basic Yii application template is a perfect fit for small projects or when you're just learning the framework.
The basic application template includes four pages: a homepage, an about page, a contact page, and a login page.
......
Creating your own Application structure
=======================================
> Note: This chapter is under development.
While [basic](apps-basic.md) and [advanced](apps-advanced.md) application templates are great for most of your needs
you may want to create your own application template to start your projects with.
......
Controller
==========
> Note: This chapter is under development.
Controller is one of the key parts of the application. It determines how to handle incoming request and creates a response.
Most often a controller takes HTTP request data and returns HTML, JSON or XML as a response.
......
Model
=====
> Note: This chapter is under development.
In keeping with the MVC approach, a model in Yii is intended for storing or temporarily representing application data, as well as defining the busines rules by which the data must abide.
Yii models have the following basic features:
......
MVC Overview
============
> Note: This chapter is under development.
Yii implements the model-view-controller (MVC) design pattern, which is
widely adopted in Web and other application programming. MVC aims to separate business logic from
user interface considerations, allowing developers to more easily change one component of an application without affecting, or even touching, another.
......
View
====
> Note: This chapter is under development.
The view component is an important part of MVC. The view acts as the interface to the application, making it responsible
for presenting data to end users, displaying forms, and so forth.
......
Fixtures
========
> Note: This chapter is under development.
Fixtures are important part of testing. Their main purpose is to set up the environment in a fixed/known state
so that your tests are repeatable and run in an expected way. Yii provides a fixture framework that allows
you to define your fixtures precisely and use them easily.
......
Debug toolbar and debugger
==========================
> Note: This chapter is under development.
Yii2 includes a handy toolbar, and built-in debugger, for faster development and debugging of your applications. The toolbar displays information
about the currently opened page, while the debugger can be used to analyze data you've previously collected (i.e., to confirm the values of variables).
......
The Gii code generation tool
============================
> Note: This chapter is under development.
Yii includes a handy tool, named Gii, that provides rapid prototyping by generating commonly used code snippets
as well as complete CRUD controllers.
......
Installation
============
> Note: This chapter is under development.
There are two ways you can install the Yii framework:
* Via [Composer](http://getcomposer.org/) (recommended)
......
Console applications
====================
> Note: This chapter is under development.
Yii has full featured support for console applications, whose structure is very similar to a Yii web application. A console application
consists of one or more [[yii\console\Controller]] classes, which are often referred to as "commands" in the console environment. Each controller can also have one or more actions, just like web controllers.
......
Error Handling
==============
> Note: This chapter is under development.
Error handling in Yii is different than handling errors in plain PHP. First of all, Yii will convert all non-fatal errors
to *exceptions*:
......
Internationalization
====================
> Note: This chapter is under development.
Internationalization (I18N) refers to the process of designing a software application so that it can be adapted to
various languages and regions without engineering changes. For Web applications, this is of particular importance
because the potential users may be worldwide.
......
Logging
=======
> Note: This chapter is under development.
Yii provides flexible and extensible logger that is able to handle messages according to severity level or their type.
You may filter messages by multiple criteria and forward them to files, email, debugger etc.
......
Performance Tuning
==================
> Note: This chapter is under development.
The performance of your web application is based upon two parts. First is the framework performance
and the second is the application itself. Yii has a pretty low performance impact
on your application out of the box and can be fine-tuned further for production
......
Using template engines
======================
> Note: This chapter is under development.
By default, Yii uses PHP as its template language, but you can configure Yii to support other rendering engines, such as
[Twig](http://twig.sensiolabs.org/) or [Smarty](http://www.smarty.net/).
......
Theming
=======
> Note: This chapter is under development.
A theme is a directory of view and layout files. Each file of the theme overrides corresponding file of an application
when rendered. A single application may use multiple themes and each may provide totally different experience. At any
time only one theme can be active.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment