Qiang Xue
12 years ago
185 changed files with 10896 additions and 10390 deletions
@ -0,0 +1,14 @@ |
|||||||
|
language: php |
||||||
|
|
||||||
|
php: |
||||||
|
- 5.3 |
||||||
|
- 5.4 |
||||||
|
- 5.5 |
||||||
|
|
||||||
|
env: |
||||||
|
- DB=mysql |
||||||
|
|
||||||
|
before_script: |
||||||
|
- sh -c "if [ '$DB' = 'mysql' ]; then mysql -e 'create database IF NOT EXISTS yiitest;'; fi" |
||||||
|
|
||||||
|
script: phpunit |
Before Width: | Height: | Size: 8.6 KiB After Width: | Height: | Size: 8.6 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
@ -0,0 +1,319 @@ |
|||||||
|
Database Migration |
||||||
|
================== |
||||||
|
|
||||||
|
Like source code, the structure of a database is evolving as we develop and maintain |
||||||
|
a database-driven application. For example, during development, we may want to |
||||||
|
add a new table; or after the application is put into production, we may realize |
||||||
|
the need of adding an index on a column. It is important to keep track of these |
||||||
|
structural database changes (called **migration**) like we do with our source |
||||||
|
code. If the source code and the database are out of sync, it is very likely |
||||||
|
the whole system may 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. |
||||||
|
|
||||||
|
The following steps show how we can use database migration during development: |
||||||
|
|
||||||
|
1. Tim creates a new migration (e.g. create a new table) |
||||||
|
2. Tim commits the new migration into source control system (e.g. GIT, Mercurial) |
||||||
|
3. Doug updates from source control system and receives the new migration |
||||||
|
4. Doug applies the migration to his local development database |
||||||
|
|
||||||
|
|
||||||
|
Yii supports database migration via the `yiic migrate` command line tool. This |
||||||
|
tool supports creating new migrations, applying/reverting/redoing migrations, and |
||||||
|
showing migration history and new migrations. |
||||||
|
|
||||||
|
Creating Migrations |
||||||
|
------------------- |
||||||
|
|
||||||
|
To create a new migration (e.g. create a news table), we run the following command: |
||||||
|
|
||||||
|
~~~ |
||||||
|
yiic migrate/create <name> |
||||||
|
~~~ |
||||||
|
|
||||||
|
The required `name` parameter specifies a very brief description of the migration |
||||||
|
(e.g. `create_news_table`). As we will show in the following, the `name` parameter |
||||||
|
is used as part of a PHP class name. Therefore, it should only contain letters, |
||||||
|
digits and/or underscore characters. |
||||||
|
|
||||||
|
~~~ |
||||||
|
yiic migrate/create create_news_table |
||||||
|
~~~ |
||||||
|
|
||||||
|
The above command will create under the `protected/migrations` directory a new |
||||||
|
file named `m101129_185401_create_news_table.php` which contains the following |
||||||
|
initial code: |
||||||
|
|
||||||
|
~~~ |
||||||
|
[php] |
||||||
|
class m101129_185401_create_news_table extends \yii\db\Migration |
||||||
|
{ |
||||||
|
public function up() |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
public function down() |
||||||
|
{ |
||||||
|
echo "m101129_185401_create_news_table cannot be reverted.\n"; |
||||||
|
return false; |
||||||
|
} |
||||||
|
} |
||||||
|
~~~ |
||||||
|
|
||||||
|
Notice that the class name is the same as the file name which is of the pattern |
||||||
|
`m<timestamp>_<name>`, where `<timestamp>` refers to the UTC timestamp (in the |
||||||
|
format of `yymmdd_hhmmss`) when the migration is created, and `<name>` is taken |
||||||
|
from the command's `name` parameter. |
||||||
|
|
||||||
|
The `up()` method should contain the code implementing the actual database |
||||||
|
migration, while the `down()` method may contain the code reverting what is |
||||||
|
done in `up()`. |
||||||
|
|
||||||
|
Sometimes, it is impossible to implement `down()`. For example, if we delete |
||||||
|
table rows in `up()`, we will not be able to recover them in `down()`. In this |
||||||
|
case, the migration is called irreversible, meaning we cannot roll back to |
||||||
|
a previous state of the database. In the above generated code, the `down()` |
||||||
|
method returns `false` to indicate that the migration cannot be reverted. |
||||||
|
|
||||||
|
As an example, let's show the migration about creating a news table. |
||||||
|
|
||||||
|
~~~ |
||||||
|
[php] |
||||||
|
class m101129_185401_create_news_table extends \yii\db\Migration |
||||||
|
{ |
||||||
|
public function up() |
||||||
|
{ |
||||||
|
$this->db->createCommand()->createTable('tbl_news, array( |
||||||
|
'id' => 'pk', |
||||||
|
'title' => 'string NOT NULL', |
||||||
|
'content' => 'text', |
||||||
|
))->execute(); |
||||||
|
} |
||||||
|
|
||||||
|
public function down() |
||||||
|
{ |
||||||
|
$this->db->createCommand()->dropTable('tbl_news')->execute(); |
||||||
|
} |
||||||
|
} |
||||||
|
~~~ |
||||||
|
|
||||||
|
The base class [\yii\db\Migration] exposes a database connection via `db` |
||||||
|
property. You can use it for manipulating data and schema of a database. |
||||||
|
|
||||||
|
Transactional Migrations |
||||||
|
------------------------ |
||||||
|
|
||||||
|
While performing complex DB migrations, we usually want to make sure that each |
||||||
|
migration succeed or fail as a whole so that the database maintains the |
||||||
|
consistency and integrity. In order to achieve this goal, we can exploit |
||||||
|
DB transactions. |
||||||
|
|
||||||
|
We could explicitly start a DB transaction and enclose the rest of the DB-related |
||||||
|
code within the transaction, like the following: |
||||||
|
|
||||||
|
~~~ |
||||||
|
[php] |
||||||
|
class m101129_185401_create_news_table extends \yii\db\Migration |
||||||
|
{ |
||||||
|
public function up() |
||||||
|
{ |
||||||
|
$transaction=$this->getDbConnection()->beginTransaction(); |
||||||
|
try |
||||||
|
{ |
||||||
|
$this->db->createCommand()->createTable('tbl_news, array( |
||||||
|
'id' => 'pk', |
||||||
|
'title' => 'string NOT NULL', |
||||||
|
'content' => 'text', |
||||||
|
))->execute(); |
||||||
|
$transaction->commit(); |
||||||
|
} |
||||||
|
catch(Exception $e) |
||||||
|
{ |
||||||
|
echo "Exception: ".$e->getMessage()."\n"; |
||||||
|
$transaction->rollback(); |
||||||
|
return false; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// ...similar code for down() |
||||||
|
} |
||||||
|
~~~ |
||||||
|
|
||||||
|
> Note: Not all DBMS support transactions. And some DB queries cannot be put |
||||||
|
> into a transaction. In this case, you will have to implement `up()` and |
||||||
|
> `down()`, instead. And for MySQL, some SQL statements may cause |
||||||
|
> [implicit commit](http://dev.mysql.com/doc/refman/5.1/en/implicit-commit.html). |
||||||
|
|
||||||
|
|
||||||
|
Applying Migrations |
||||||
|
------------------- |
||||||
|
|
||||||
|
To apply all available new migrations (i.e., make the local database up-to-date), |
||||||
|
run the following command: |
||||||
|
|
||||||
|
~~~ |
||||||
|
yiic migrate |
||||||
|
~~~ |
||||||
|
|
||||||
|
The command will show the list of all new migrations. If you confirm to apply |
||||||
|
the migrations, it will run the `up()` method in every new migration class, one |
||||||
|
after another, in the order of the timestamp value in the class name. |
||||||
|
|
||||||
|
After applying a migration, the migration tool will keep a record in a database |
||||||
|
table named `tbl_migration`. This allows the tool to identify which migrations |
||||||
|
have been applied and which are not. If the `tbl_migration` table does not exist, |
||||||
|
the tool will automatically create it in the database specified by the `db` |
||||||
|
application component. |
||||||
|
|
||||||
|
Sometimes, we may only want to apply one or a few new migrations. We can use the |
||||||
|
following command: |
||||||
|
|
||||||
|
~~~ |
||||||
|
yiic migrate/up 3 |
||||||
|
~~~ |
||||||
|
|
||||||
|
This command will apply the 3 new migrations. Changing the value 3 will allow |
||||||
|
us to change the number of migrations to be applied. |
||||||
|
|
||||||
|
We can also migrate the database to a specific version with the following command: |
||||||
|
|
||||||
|
~~~ |
||||||
|
yiic migrate/to 101129_185401 |
||||||
|
~~~ |
||||||
|
|
||||||
|
That is, we use the timestamp part of a migration name to specify the version |
||||||
|
that we want to migrate the database to. If there are multiple migrations between |
||||||
|
the last applied migration and the specified migration, all these migrations |
||||||
|
will be applied. If the specified migration has been applied before, then all |
||||||
|
migrations applied after it will be reverted (to be described in the next section). |
||||||
|
|
||||||
|
|
||||||
|
Reverting Migrations |
||||||
|
-------------------- |
||||||
|
|
||||||
|
To revert the last one or several applied migrations, we can use the following |
||||||
|
command: |
||||||
|
|
||||||
|
~~~ |
||||||
|
yiic migrate/down [step] |
||||||
|
~~~ |
||||||
|
|
||||||
|
where the optional `step` parameter specifies how many migrations to be reverted |
||||||
|
back. It defaults to 1, meaning reverting back the last applied migration. |
||||||
|
|
||||||
|
As we described before, not all migrations can be reverted. Trying to revert |
||||||
|
such migrations will throw an exception and stop the whole reverting process. |
||||||
|
|
||||||
|
|
||||||
|
Redoing Migrations |
||||||
|
------------------ |
||||||
|
|
||||||
|
Redoing migrations means first reverting and then applying the specified migrations. |
||||||
|
This can be done with the following command: |
||||||
|
|
||||||
|
~~~ |
||||||
|
yiic migrate/redo [step] |
||||||
|
~~~ |
||||||
|
|
||||||
|
where the optional `step` parameter specifies how many migrations to be redone. |
||||||
|
It defaults to 1, meaning redoing the last migration. |
||||||
|
|
||||||
|
|
||||||
|
Showing Migration Information |
||||||
|
----------------------------- |
||||||
|
|
||||||
|
Besides applying and reverting migrations, the migration tool can also display |
||||||
|
the migration history and the new migrations to be applied. |
||||||
|
|
||||||
|
~~~ |
||||||
|
yiic migrate/history [limit] |
||||||
|
yiic migrate/new [limit] |
||||||
|
~~~ |
||||||
|
|
||||||
|
where the optional parameter `limit` specifies the number of migrations to be |
||||||
|
displayed. If `limit` is not specified, all available migrations will be displayed. |
||||||
|
|
||||||
|
The first command shows the migrations that have been applied, while the second |
||||||
|
command shows the migrations that have not been applied. |
||||||
|
|
||||||
|
|
||||||
|
Modifying Migration History |
||||||
|
--------------------------- |
||||||
|
|
||||||
|
Sometimes, we may want to modify the migration history to a specific migration |
||||||
|
version without actually applying or reverting the relevant migrations. This |
||||||
|
often happens when developing a new migration. We can use the following command |
||||||
|
to achieve this goal. |
||||||
|
|
||||||
|
~~~ |
||||||
|
yiic migrate/mark 101129_185401 |
||||||
|
~~~ |
||||||
|
|
||||||
|
This command is very similar to `yiic migrate/to` command, except that it only |
||||||
|
modifies the migration history table to the specified version without applying |
||||||
|
or reverting the migrations. |
||||||
|
|
||||||
|
|
||||||
|
Customizing Migration Command |
||||||
|
----------------------------- |
||||||
|
|
||||||
|
There are several ways to customize the migration command. |
||||||
|
|
||||||
|
### Use Command Line Options |
||||||
|
|
||||||
|
The migration command comes with four options that can be specified in command |
||||||
|
line: |
||||||
|
|
||||||
|
* `interactive`: boolean, specifies whether to perform migrations in an |
||||||
|
interactive mode. Defaults to true, meaning the user will be prompted when |
||||||
|
performing a specific migration. You may set this to false should the |
||||||
|
migrations be done in a background process. |
||||||
|
|
||||||
|
* `migrationPath`: string, specifies the directory storing all migration class |
||||||
|
files. This must be specified in terms of a path alias, and the corresponding |
||||||
|
directory must exist. If not specified, it will use the `migrations` |
||||||
|
sub-directory under the application base path. |
||||||
|
|
||||||
|
* `migrationTable`: string, specifies the name of the database table for storing |
||||||
|
migration history information. It defaults to `tbl_migration`. The table |
||||||
|
structure is `version varchar(255) primary key, apply_time integer`. |
||||||
|
|
||||||
|
* `connectionID`: string, specifies the ID of the database application component. |
||||||
|
Defaults to 'db'. |
||||||
|
|
||||||
|
* `templateFile`: string, specifies the path of the file to be served as the code |
||||||
|
template for generating the migration classes. This must be specified in terms |
||||||
|
of a path alias (e.g. `application.migrations.template`). If not set, an |
||||||
|
internal template will be used. Inside the template, the token `{ClassName}` |
||||||
|
will be replaced with the actual migration class name. |
||||||
|
|
||||||
|
To specify these options, execute the migrate command using the following format |
||||||
|
|
||||||
|
~~~ |
||||||
|
yiic migrate/up --option1=value1 --option2=value2 ... |
||||||
|
~~~ |
||||||
|
|
||||||
|
For example, if we want to migrate for a `forum` module whose migration files |
||||||
|
are located within the module's `migrations` directory, we can use the following |
||||||
|
command: |
||||||
|
|
||||||
|
~~~ |
||||||
|
yiic migrate/up --migrationPath=ext.forum.migrations |
||||||
|
~~~ |
||||||
|
|
||||||
|
|
||||||
|
### Configure Command Globally |
||||||
|
|
||||||
|
While command line options allow us to configure the migration command |
||||||
|
on-the-fly, sometimes we may want to configure the command once for all. |
||||||
|
For example, we may want to use a different table to store the migration history, |
||||||
|
or we may want to use a customized migration template. We can do so by modifying |
||||||
|
the console application's configuration file like the following, |
||||||
|
|
||||||
|
```php |
||||||
|
TBD |
||||||
|
``` |
||||||
|
|
||||||
|
Now if we run the `migrate` command, the above configurations will take effect |
||||||
|
without requiring us to enter the command line options every time. |
@ -0,0 +1,181 @@ |
|||||||
|
Performance Tuning |
||||||
|
================== |
||||||
|
|
||||||
|
Application performance consists of 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 |
||||||
|
environment. As for the application, we'll provide some of the best practices |
||||||
|
along with examples on how to apply them to Yii. |
||||||
|
|
||||||
|
Preparing framework for production |
||||||
|
---------------------------------- |
||||||
|
|
||||||
|
### Disabling Debug Mode |
||||||
|
|
||||||
|
First thing you should do before deploying your application to production environment |
||||||
|
is to disable debug mode. A Yii application runs in debug mode if the constant |
||||||
|
`YII_DEBUG` is defined as `true` in `index.php` so to disable debug the following |
||||||
|
should be in your `index.php`: |
||||||
|
|
||||||
|
```php |
||||||
|
defined('YII_DEBUG') or define('YII_DEBUG', false); |
||||||
|
``` |
||||||
|
|
||||||
|
Debug mode is very useful during development stage, but it would impact performance |
||||||
|
because some components cause extra burden in debug mode. For example, the message |
||||||
|
logger may record additional debug information for every message being logged. |
||||||
|
|
||||||
|
### Enabling PHP opcode cache |
||||||
|
|
||||||
|
Enabling the PHP opcode cache improves any PHP application performance and lowers |
||||||
|
memory usage significantly. Yii is no exception. It was tested with |
||||||
|
[APC PHP extension](http://php.net/manual/en/book.apc.php) that caches |
||||||
|
and optimizes PHP intermediate code and avoids the time spent in parsing PHP |
||||||
|
scripts for every incoming request. |
||||||
|
|
||||||
|
### Turning on ActiveRecord database schema caching |
||||||
|
|
||||||
|
If the application is using Active Record, we should turn on the schema caching |
||||||
|
to save the time of parsing database schema. This can be done by setting the |
||||||
|
`Connection::enableSchemaCache` property to be `true` via application configuration |
||||||
|
`protected/config/main.php`: |
||||||
|
|
||||||
|
```php |
||||||
|
return array( |
||||||
|
// ... |
||||||
|
'components' => array( |
||||||
|
// ... |
||||||
|
'db' => array( |
||||||
|
'class' => 'yii\db\Connection', |
||||||
|
'dsn' => 'mysql:host=localhost;dbname=mydatabase', |
||||||
|
'username' => 'root', |
||||||
|
'password' => '', |
||||||
|
'enableSchemaCache' => true, |
||||||
|
|
||||||
|
// Duration of schema cache. |
||||||
|
// 'schemaCacheDuration' => 3600, |
||||||
|
|
||||||
|
// Name of the cache component used. Default is 'cache'. |
||||||
|
//'schemaCache' => 'cache', |
||||||
|
), |
||||||
|
'cache' => array( |
||||||
|
'class' => 'yii\caching\FileCache', |
||||||
|
), |
||||||
|
), |
||||||
|
); |
||||||
|
``` |
||||||
|
|
||||||
|
Note that `cache` application component should be configured. |
||||||
|
|
||||||
|
### Combining and Minimizing Assets |
||||||
|
|
||||||
|
TBD |
||||||
|
|
||||||
|
### Using better storage for sessions |
||||||
|
|
||||||
|
By default PHP uses files to handle sessions. It is OK for development and |
||||||
|
small projects but when it comes to handling concurrent requests it's better to |
||||||
|
switch to another storage such as database. You can do so by configuring your |
||||||
|
application via `protected/config/main.php`: |
||||||
|
|
||||||
|
```php |
||||||
|
return array( |
||||||
|
// ... |
||||||
|
'components' => array( |
||||||
|
'session' => array( |
||||||
|
'class' => 'yii\web\DbSession', |
||||||
|
|
||||||
|
// Set the following if want to use DB component other than |
||||||
|
// default 'db'. |
||||||
|
// 'db' => 'mydb', |
||||||
|
|
||||||
|
// To override default session table set the following |
||||||
|
// 'sessionTable' => 'my_session', |
||||||
|
), |
||||||
|
), |
||||||
|
); |
||||||
|
``` |
||||||
|
|
||||||
|
You can use `CacheSession` to store sessions using cache. Note that some |
||||||
|
cache storages such as memcached has no guaranteee that session data will not |
||||||
|
be lost leading to unexpected logouts. |
||||||
|
|
||||||
|
Improving application |
||||||
|
--------------------- |
||||||
|
|
||||||
|
### Using Serverside Caching Techniques |
||||||
|
|
||||||
|
As described in the Caching section, Yii provides several caching solutions that |
||||||
|
may improve the performance of a Web application significantly. If the generation |
||||||
|
of some data takes long time, we can use the data caching approach to reduce the |
||||||
|
data generation frequency; If a portion of page remains relatively static, we |
||||||
|
can use the fragment caching approach to reduce its rendering frequency; |
||||||
|
If a whole page remains relative static, we can use the page caching approach to |
||||||
|
save the rendering cost for the whole page. |
||||||
|
|
||||||
|
|
||||||
|
### Leveraging HTTP to save procesing time and bandwidth |
||||||
|
|
||||||
|
TBD |
||||||
|
|
||||||
|
### Database Optimization |
||||||
|
|
||||||
|
Fetching data from database is often the main performance bottleneck in |
||||||
|
a Web application. Although using caching may alleviate the performance hit, |
||||||
|
it does not fully solve the problem. When the database contains enormous data |
||||||
|
and the cached data is invalid, fetching the latest data could be prohibitively |
||||||
|
expensive without proper database and query design. |
||||||
|
|
||||||
|
Design index wisely in a database. Indexing can make SELECT queries much faster, |
||||||
|
but it may slow down INSERT, UPDATE or DELETE queries. |
||||||
|
|
||||||
|
For complex queries, it is recommended to create a database view for it instead |
||||||
|
of issuing the queries inside the PHP code and asking DBMS to parse them repetitively. |
||||||
|
|
||||||
|
Do not overuse Active Record. Although Active Record is good at modelling data |
||||||
|
in an OOP fashion, it actually degrades performance due to the fact that it needs |
||||||
|
to create one or several objects to represent each row of query result. For data |
||||||
|
intensive applications, using DAO or database APIs at lower level could be |
||||||
|
a better choice. |
||||||
|
|
||||||
|
Last but not least, use LIMIT in your SELECT queries. This avoids fetching |
||||||
|
overwhelming data from database and exhausting the memory allocated to PHP. |
||||||
|
|
||||||
|
### Using asArray |
||||||
|
|
||||||
|
A good way to save memory and processing time on read-only pages is to use |
||||||
|
ActiveRecord's `asArray` method. |
||||||
|
|
||||||
|
```php |
||||||
|
class PostController extends Controller |
||||||
|
{ |
||||||
|
public function actionIndex() |
||||||
|
{ |
||||||
|
$posts = Post::find()->orderBy('id DESC')->limit(100)->asArray()->all(); |
||||||
|
echo $this->render('index', array( |
||||||
|
'posts' => $posts, |
||||||
|
)); |
||||||
|
} |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
In the view you should access fields of each invidual record from `$posts` as array: |
||||||
|
|
||||||
|
```php |
||||||
|
foreach($posts as $post) { |
||||||
|
echo $post['title']."<br>"; |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
Note that you can use array notation even if `asArray` wasn't specified and you're |
||||||
|
working with AR objects. |
||||||
|
|
||||||
|
### Processing data in background |
||||||
|
|
||||||
|
In order to respond to user requests faster you can process heavy parts of the |
||||||
|
request later if there's no need for immediate response. |
||||||
|
|
||||||
|
- Cron jobs + console. |
||||||
|
- queues + handlers. |
||||||
|
|
||||||
|
TBD |
@ -1,17 +0,0 @@ |
|||||||
<?php |
|
||||||
/** @var $controller \yii\console\controllers\AppController */ |
|
||||||
$controller = $this; |
|
||||||
|
|
||||||
return array( |
|
||||||
'default' => array( |
|
||||||
'index.php' => array( |
|
||||||
'handler' => function($source) use ($controller) { |
|
||||||
return $controller->replaceRelativePath($source, realpath(YII_PATH.'/yii.php'), 'yii'); |
|
||||||
}, |
|
||||||
'permissions' => 0777, |
|
||||||
), |
|
||||||
'protected/runtime' => array( |
|
||||||
'permissions' => 0755, |
|
||||||
), |
|
||||||
), |
|
||||||
); |
|
@ -1,10 +0,0 @@ |
|||||||
<?php |
|
||||||
define('YII_DEBUG', true); |
|
||||||
|
|
||||||
require __DIR__.'/../framework/yii.php'; |
|
||||||
|
|
||||||
$config = require dirname(__DIR__).'/protected/config/main.php'; |
|
||||||
$config['basePath'] = dirname(__DIR__).'/protected'; |
|
||||||
|
|
||||||
$app = new \yii\web\Application($config); |
|
||||||
$app->run(); |
|
@ -1,20 +0,0 @@ |
|||||||
<?php |
|
||||||
return array( |
|
||||||
'id' => 'webapp', |
|
||||||
'name' => 'My Web Application', |
|
||||||
|
|
||||||
'components' => array( |
|
||||||
// uncomment the following to use a MySQL database |
|
||||||
/* |
|
||||||
'db' => array( |
|
||||||
'class' => 'yii\db\Connection', |
|
||||||
'dsn' => 'mysql:host=localhost;dbname=testdrive', |
|
||||||
'username' => 'root', |
|
||||||
'password' => '', |
|
||||||
), |
|
||||||
*/ |
|
||||||
'cache' => array( |
|
||||||
'class' => 'yii\caching\DummyCache', |
|
||||||
), |
|
||||||
), |
|
||||||
); |
|
@ -1,15 +0,0 @@ |
|||||||
<?php |
|
||||||
use \yii\web\Controller; |
|
||||||
|
|
||||||
/** |
|
||||||
* SiteController |
|
||||||
*/ |
|
||||||
class SiteController extends Controller |
|
||||||
{ |
|
||||||
public function actionIndex() |
|
||||||
{ |
|
||||||
echo $this->render('index', array( |
|
||||||
'name' => 'Qiang', |
|
||||||
)); |
|
||||||
} |
|
||||||
} |
|
@ -1,17 +0,0 @@ |
|||||||
<?php use yii\helpers\Html as Html; ?> |
|
||||||
<!doctype html> |
|
||||||
<html lang="<?php \Yii::$app->language?>">
|
|
||||||
<head> |
|
||||||
<meta charset="utf-8" /> |
|
||||||
<title><?php echo Html::encode($this->title)?></title>
|
|
||||||
</head> |
|
||||||
<body> |
|
||||||
<h1><?php echo Html::encode($this->title)?></h1>
|
|
||||||
<div class="content"> |
|
||||||
<?php echo $content?> |
|
||||||
</div> |
|
||||||
<div class="footer"> |
|
||||||
<?php echo \Yii::powered()?> |
|
||||||
</div> |
|
||||||
</body> |
|
||||||
</html> |
|
@ -1 +0,0 @@ |
|||||||
Hello, <?php echo $name?>!
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue