1. Create a new repository, shuijingwan/yii2-app-advanced, as shown in Figure 1
The Yii 2 advanced project template includes four tiers: API (implementing RESTful-style Web Service APIs), frontend, backend, and console, each of which is a separate Yii application.

2. The repository was created successfully, as shown in Figure 2

3. Install the application using the following command: yiisoft/yii2-app-advanced, as shown in Figure 3

composer self-update
composer global require "fxp/composer-asset-plugin"
composer create-project --prefer-dist yiisoft/yii2-app-advanced github-shuijingwan-yii2-app-advanced
4. Create a new repository from the command line and push the existing repository to shuijingwan/yii2-app-advanced, based on step 2, as shown in Figure 4

git init
git add .
git commit -m "安装 yiisoft/yii2-app-advanced 后,全部提交。"
git remote add origin https://github.com/shuijingwan/yii2-app-advanced.git
git push -u origin master
5. Open: https://github.com/shuijingwan/yii2-app-advanced , the repository has been pushed successfully, as shown in Figure 5

6. Open Windows PowerShell, run the init command, and select dev as the environment, as shown in Figure 6

.\init
0
yes
7. Modify the hosts file to point the domain to your server by configuring the C:\Windows\System32\drivers\etc\hosts file, as shown in Figure 7

# github-shuijingwan-yii2-app-advanced
127.0.0.1 github-shuijingwan-yii2-app-advanced.localhost www.github-shuijingwan-yii2-app-advanced.localhost backend.github-shuijingwan-yii2-app-advanced.localhost api.github-shuijingwan-yii2-app-advanced.localhost
8. Configure the web server based on Nginx. Set up virtual hosts: www and backend; the api configuration is postponed for now. Edit C:\nginx-1.10.1\conf\vhosts\github-shuijingwan-yii2-app-advanced.conf
## FRONTEND ##
server {
charset utf-8;
client_max_body_size 128M;
listen 80; ## listen for ipv4
#listen [::]:80 default_server ipv6only=on; ## listen for ipv6
server_name www.github-shuijingwan-yii2-app-advanced.localhost;
root E:/wwwroot/github-shuijingwan-yii2-app-advanced/frontend/web;
index index.php;
access_log logs/www.github-shuijingwan-yii2-app-advanced.localhost.access.log;
error_log logs/www.github-shuijingwan-yii2-app-advanced.localhost.error.log;
location / {
# Redirect everything that isn't a real file to index.php
try_files $uri $uri/ /index.php$is_args$args;
}
# uncomment to avoid processing of calls to non-existing static files by Yii
#location ~ \.(js|css|png|jpg|gif|swf|ico|pdf|mov|fla|zip|rar)$ {
# try_files $uri =404;
#}
#error_page 404 /404.html;
# deny accessing php files for the /assets directory
location ~ ^/assets/.*\.php$ {
deny all;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass 127.0.0.1:9000;
#fastcgi_pass unix:/var/run/php5-fpm.sock;
try_files $uri =404;
}
location ~* /\. {
deny all;
}
}
## BACKEND ##
server {
charset utf-8;
client_max_body_size 128M;
listen 80; ## listen for ipv4
#listen [::]:80 default_server ipv6only=on; ## listen for ipv6
server_name backend.github-shuijingwan-yii2-app-advanced.localhost;
root E:/wwwroot/github-shuijingwan-yii2-app-advanced/backend/web;
index index.php;
access_log logs/backend.github-shuijingwan-yii2-app-advanced.localhost.access.log;
error_log logs/backend.github-shuijingwan-yii2-app-advanced.localhost.error.log;
location / {
# Redirect everything that isn't a real file to index.php
try_files $uri $uri/ /index.php$is_args$args;
}
# uncomment to avoid processing of calls to non-existing static files by Yii
#location ~ \.(js|css|png|jpg|gif|swf|ico|pdf|mov|fla|zip|rar)$ {
# try_files $uri =404;
#}
#error_page 404 /404.html;
# deny accessing php files for the /assets directory
location ~ ^/assets/.*\.php$ {
deny all;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass 127.0.0.1:9000;
#fastcgi_pass unix:/var/run/php5-fpm.sock;
try_files $uri =404;
}
location ~* /\. {
deny all;
}
}
## MISC ##
### WWW Redirect ###
server {
listen 80;
server_name github-shuijingwan-yii2-app-advanced.localhost;
return 301 http://www.github-shuijingwan-yii2-app-advanced.localhost$request_uri;
}
9. Check whether the current PHP environment meets the basic requirements of Yii. Copy /requirements.php to /frontend/web/requirements.php, and then access the URL http://www.github-shuijingwan-yii2-app-advanced.localhost/requirements.php via a browser, as shown in Figure 8

$frameworkPath = dirname(__FILE__) . '/../../vendor/yiisoft/yii2';
10. Create a new database (g-s-yii2-app-advanced) and adjust the components[‘db’] configuration in /common/config/main-local.php accordingly, setting the character set to utf8mb4.
CREATE USER 'g-s-yii2-app-advanced'@'%' IDENTIFIED WITH mysql_native_password AS '***';GRANT USAGE ON *.* TO 'g-s-yii2-app-advanced'@'%' REQUIRE NONE WITH MAX_QUERIES_PER_HOUR 0 MAX_CONNECTIONS_PER_HOUR 0 MAX_UPDATES_PER_HOUR 0 MAX_USER_CONNECTIONS 0;CREATE DATABASE IF NOT EXISTS `g-s-yii2-app-advanced`;GRANT ALL PRIVILEGES ON `g-s-yii2-app-advanced`.* TO 'g-s-yii2-app-advanced'@'%';
'db' => [
'class' => 'yii\db\Connection',
'dsn' => 'mysql:host=localhost;dbname=g-s-yii2-app-advanced',
'username' => 'g-s-yii2-app-advanced',
'password' => 'IADO0x7uK4UpaRRM',
'charset' => 'utf8mb4',
],
11. Run the migration command, as shown in Figure 9

.\yii migrate
yes
12. Check the database; the collation is: utf8mb4_unicode_ci, as shown in Figure 10

13. Create a test database (g-s-yii2-app-advanced-test) and adjust the components[‘db’] configuration in /common/config/test-local.php accordingly, setting the character set to utf8mb4.
CREATE USER 'g-s-yii2-app-advanced-test'@'%' IDENTIFIED WITH mysql_native_password AS '***';GRANT USAGE ON *.* TO 'g-s-yii2-app-advanced-test'@'%' REQUIRE NONE WITH MAX_QUERIES_PER_HOUR 0 MAX_CONNECTIONS_PER_HOUR 0 MAX_UPDATES_PER_HOUR 0 MAX_USER_CONNECTIONS 0;CREATE DATABASE IF NOT EXISTS `g-s-yii2-app-advanced-test`;GRANT ALL PRIVILEGES ON `g-s-yii2-app-advanced-test`.* TO 'g-s-yii2-app-advanced-test'@'%';
'db' => [
'dsn' => 'mysql:host=localhost;dbname=g-s-yii2-app-advanced-test',
'username' => 'g-s-yii2-app-advanced-test',
'password' => '9dIXzEvrGN9akpcO',
'charset' => 'utf8mb4',
]
14. Run the migration command, which throws an error: Exception ‘yii\base\UnknownPropertyException’ with message ‘Setting unknown property: yii\console\Request::cookieValidat
ionKey’ in E:\wwwroot\github-shuijingwan-yii2-app-advanced\vendor\yiisoft\yii2\base\Component.php:209, as shown in Figure 11

./yii_test migrate
15. Because the console application uses a different request component, edit \common\config\test.php and comment out the request component (it needs to be uncommented in web applications), as shown in Figure 12

'components' => [
'user' => [
'class' => 'yii\web\User',
'identityClass' => 'common\models\User',
],
/*
'request' => [
'cookieValidationKey' => 'test',
],
*/
],
16. Run the migration command, build the test suite, and then run all sample tests, as shown in Figure 13
Note: After running the migration command (./yii_test migrate), you must uncomment the request component; otherwise, the following error will occur:

Test ..\common\tests\unit\models\LoginFormTest.php:testLoginCorrect
[yii\base\InvalidConfigException] yii\web\Request::cookieValidationKey must be configured with a secret key.
./yii_test migrate
vendor/bin/codecept build
vendor/bin/codecept run
17. Check the test database; the collation is: utf8mb4_unicode_ci, as shown in Figure 14

18. Add the API application (api). Copy frontend to api, environments/dev/frontend to environments/dev/api, and environments/prod/frontend to environments/prod/api, as shown in Figure 15

19. Delete all files under the \api\runtime\debug directory. In the /api directory, adjust the namespaces and paths to start with api (replace frontend with api), as shown in Figure 16

20. Add Yii::setAlias(‘api’, dirname(dirname(__DIR__)) . ‘/api’); to common\config\bootstrap.php, as shown in Figure 17

21. Edit environments/index.php. A search shows there are 6 instances of frontend in this file; copy them 6 times accordingly and replace them with api, as shown in Figure 18

22. In \vagrant\nginx\app.conf, add a new virtual host api
\vagrant\nginx\app.conf
server {
charset utf-8;
client_max_body_size 128M;
sendfile off;
listen 80; ## listen for ipv4
#listen [::]:80 default_server ipv6only=on; ## listen for ipv6
server_name y2aa-frontend.test;
root /app/frontend/web/;
index index.php;
access_log /app/vagrant/nginx/log/frontend-access.log;
error_log /app/vagrant/nginx/log/frontend-error.log;
location / {
# Redirect everything that isn't a real file to index.php
try_files $uri $uri/ /index.php$is_args$args;
}
# uncomment to avoid processing of calls to non-existing static files by Yii
#location ~ \.(js|css|png|jpg|gif|swf|ico|pdf|mov|fla|zip|rar)$ {
# try_files $uri =404;
#}
#error_page 404 /404.html;
location ~ \.php$ {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
#fastcgi_pass 127.0.0.1:9000;
fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
try_files $uri =404;
}
location ~ /\.(ht|svn|git) {
deny all;
}
}
server {
charset utf-8;
client_max_body_size 128M;
sendfile off;
listen 80; ## listen for ipv4
#listen [::]:80 default_server ipv6only=on; ## listen for ipv6
server_name y2aa-backend.test;
root /app/backend/web/;
index index.php;
access_log /app/vagrant/nginx/log/backend-access.log;
error_log /app/vagrant/nginx/log/backend-error.log;
location / {
# Redirect everything that isn't a real file to index.php
try_files $uri $uri/ /index.php$is_args$args;
}
# uncomment to avoid processing of calls to non-existing static files by Yii
#location ~ \.(js|css|png|jpg|gif|swf|ico|pdf|mov|fla|zip|rar)$ {
# try_files $uri =404;
#}
#error_page 404 /404.html;
location ~ \.php$ {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
#fastcgi_pass 127.0.0.1:9000;
fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
try_files $uri =404;
}
location ~ /\.(ht|svn|git) {
deny all;
}
}
server {
charset utf-8;
client_max_body_size 128M;
sendfile off;
listen 80; ## listen for ipv4
#listen [::]:80 default_server ipv6only=on; ## listen for ipv6
server_name y2aa-api.test;
root /app/api/web/;
index index.php;
access_log /app/vagrant/nginx/log/api-access.log;
error_log /app/vagrant/nginx/log/api-error.log;
location / {
# Redirect everything that isn't a real file to index.php
try_files $uri $uri/ /index.php$is_args$args;
}
# uncomment to avoid processing of calls to non-existing static files by Yii
#location ~ \.(js|css|png|jpg|gif|swf|ico|pdf|mov|fla|zip|rar)$ {
# try_files $uri =404;
#}
#error_page 404 /404.html;
location ~ \.php$ {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
#fastcgi_pass 127.0.0.1:9000;
fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
try_files $uri =404;
}
location ~ /\.(ht|svn|git) {
deny all;
}
}
23. Edit \vagrant\nginx\log\.gitignore to configure the api log files to be ignored
# nginx logs
backend-access.log
backend-error.log
frontend-access.log
frontend-error.log
api-access.log
api-error.log
24. Edit \Vagrantfile to add api-related configurations
require 'yaml'
require 'fileutils'
required_plugins = %w( vagrant-hostmanager vagrant-vbguest )
required_plugins.each do |plugin|
exec "vagrant plugin install #{plugin}" unless Vagrant.has_plugin? plugin
end
domains = {
frontend: 'y2aa-frontend.test',
backend: 'y2aa-backend.test',
api: 'y2aa-api.test',
}
config = {
local: './vagrant/config/vagrant-local.yml',
example: './vagrant/config/vagrant-local.example.yml'
}
# copy config from example if local config not exists
FileUtils.cp config[:example], config[:local] unless File.exist?(config[:local])
# read config
options = YAML.load_file config[:local]
# check github token
if options['github_token'].nil? || options['github_token'].to_s.length != 40
puts "You must place REAL GitHub token into configuration:\n/yii2-app-advanced/vagrant/config/vagrant-local.yml"
exit
end
# vagrant configurate
Vagrant.configure(2) do |config|
# select the box
config.vm.box = 'bento/ubuntu-16.04'
# should we ask about box updates?
config.vm.box_check_update = options['box_check_update']
config.vm.provider 'virtualbox' do |vb|
# machine cpus count
vb.cpus = options['cpus']
# machine memory size
vb.memory = options['memory']
# machine name (for VirtualBox UI)
vb.name = options['machine_name']
end
# machine name (for vagrant console)
config.vm.define options['machine_name']
# machine name (for guest machine console)
config.vm.hostname = options['machine_name']
# network settings
config.vm.network 'private_network', ip: options['ip']
# sync: folder 'yii2-app-advanced' (host machine) -> folder '/app' (guest machine)
config.vm.synced_folder './', '/app', owner: 'vagrant', group: 'vagrant'
# disable folder '/vagrant' (guest machine)
config.vm.synced_folder '.', '/vagrant', disabled: true
# hosts settings (host machine)
config.vm.provision :hostmanager
config.hostmanager.enabled = true
config.hostmanager.manage_host = true
config.hostmanager.ignore_private_ip = false
config.hostmanager.include_offline = true
config.hostmanager.aliases = domains.values
# provisioners
config.vm.provision 'shell', path: './vagrant/provision/once-as-root.sh', args: [options['timezone']]
config.vm.provision 'shell', path: './vagrant/provision/once-as-vagrant.sh', args: [options['github_token']], privileged: false
config.vm.provision 'shell', path: './vagrant/provision/always-as-root.sh', run: 'always'
# post-install message (vagrant console)
config.vm.post_up_message = "Frontend URL: http://#{domains[:frontend]}\nBackend URL: http://#{domains[:backend]}\nApi URL: http://#{domains[:api]}"
end
25. Configure the web server based on Nginx. Set up virtual hosts: www, backend, and api. Edit C:\nginx-1.10.1\conf\vhosts\github-shuijingwan-yii2-app-advanced.conf
## FRONTEND ##
server {
charset utf-8;
client_max_body_size 128M;
listen 80; ## listen for ipv4
#listen [::]:80 default_server ipv6only=on; ## listen for ipv6
server_name www.github-shuijingwan-yii2-app-advanced.localhost;
root E:/wwwroot/github-shuijingwan-yii2-app-advanced/frontend/web;
index index.php;
access_log logs/www.github-shuijingwan-yii2-app-advanced.localhost.access.log;
error_log logs/www.github-shuijingwan-yii2-app-advanced.localhost.error.log;
location / {
# Redirect everything that isn't a real file to index.php
try_files $uri $uri/ /index.php$is_args$args;
}
# uncomment to avoid processing of calls to non-existing static files by Yii
#location ~ \.(js|css|png|jpg|gif|swf|ico|pdf|mov|fla|zip|rar)$ {
# try_files $uri =404;
#}
#error_page 404 /404.html;
# deny accessing php files for the /assets directory
location ~ ^/assets/.*\.php$ {
deny all;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass 127.0.0.1:9000;
#fastcgi_pass unix:/var/run/php5-fpm.sock;
try_files $uri =404;
}
location ~* /\. {
deny all;
}
}
## BACKEND ##
server {
charset utf-8;
client_max_body_size 128M;
listen 80; ## listen for ipv4
#listen [::]:80 default_server ipv6only=on; ## listen for ipv6
server_name backend.github-shuijingwan-yii2-app-advanced.localhost;
root E:/wwwroot/github-shuijingwan-yii2-app-advanced/backend/web;
index index.php;
access_log logs/backend.github-shuijingwan-yii2-app-advanced.localhost.access.log;
error_log logs/backend.github-shuijingwan-yii2-app-advanced.localhost.error.log;
location / {
# Redirect everything that isn't a real file to index.php
try_files $uri $uri/ /index.php$is_args$args;
}
# uncomment to avoid processing of calls to non-existing static files by Yii
#location ~ \.(js|css|png|jpg|gif|swf|ico|pdf|mov|fla|zip|rar)$ {
# try_files $uri =404;
#}
#error_page 404 /404.html;
# deny accessing php files for the /assets directory
location ~ ^/assets/.*\.php$ {
deny all;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass 127.0.0.1:9000;
#fastcgi_pass unix:/var/run/php5-fpm.sock;
try_files $uri =404;
}
location ~* /\. {
deny all;
}
}
## API ##
server {
charset utf-8;
client_max_body_size 128M;
listen 80; ## listen for ipv4
#listen [::]:80 default_server ipv6only=on; ## listen for ipv6
server_name api.github-shuijingwan-yii2-app-advanced.localhost;
root E:/wwwroot/github-shuijingwan-yii2-app-advanced/api/web;
index index.php;
access_log logs/api.github-shuijingwan-yii2-app-advanced.localhost.access.log;
error_log logs/api.github-shuijingwan-yii2-app-advanced.localhost.error.log;
location / {
# Redirect everything that isn't a real file to index.php
try_files $uri $uri/ /index.php$is_args$args;
}
# uncomment to avoid processing of calls to non-existing static files by Yii
#location ~ \.(js|css|png|jpg|gif|swf|ico|pdf|mov|fla|zip|rar)$ {
# try_files $uri =404;
#}
#error_page 404 /404.html;
# deny accessing php files for the /assets directory
location ~ ^/assets/.*\.php$ {
deny all;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass 127.0.0.1:9000;
#fastcgi_pass unix:/var/run/php5-fpm.sock;
try_files $uri =404;
}
location ~* /\. {
deny all;
}
}
## MISC ##
### WWW Redirect ###
server {
listen 80;
server_name github-shuijingwan-yii2-app-advanced.localhost;
return 301 http://www.github-shuijingwan-yii2-app-advanced.localhost$request_uri;
}
26. Open Windows PowerShell, run the init command, and select dev as the environment. The environment configuration files required by the api application are generated automatically, as shown in Figure 19

.\init
0
yes
Yes
Yes
Yes
Yes
Yes
27. Open: http://api.github-shuijingwan-yii2-app-advanced.localhost/ , which works as expected, as shown in Figure 20

28. Edit codeception.yml to configure tests that include all applications, as shown in Figure 21

# global codeception file to run tests from all apps
include:
- common
- frontend
- backend
- api
paths:
log: console/runtime/logs
settings:
colors: true
29. Run all sample tests, including api, as shown in Figure 22

vendor/bin/codecept run
30. Edit README.md to add api to the directory structure
Yii 2 Advanced Project Template
Yii 2 Advanced Project Template is a skeleton [Yii 2](http://www.yiiframework.com/) application best for
developing complex Web applications with multiple tiers.
The template includes three tiers: front end, back end, and console, each of which
is a separate Yii application.
The template is designed to work in a team development environment. It supports
deploying the application in different environments.
Documentation is at [docs/guide/README.md](docs/guide/README.md).
[](https://packagist.org/packages/yiisoft/yii2-app-advanced)
[](https://packagist.org/packages/yiisoft/yii2-app-advanced)
[](https://travis-ci.org/yiisoft/yii2-app-advanced)
DIRECTORY STRUCTURE
-------------------
```
common
config/ contains shared configurations
mail/ contains view files for e-mails
models/ contains model classes used in both api and backend and frontend
tests/ contains tests for common classes
console
config/ contains console configurations
controllers/ contains console controllers (commands)
migrations/ contains database migrations
models/ contains console-specific model classes
runtime/ contains files generated during runtime
backend
assets/ contains application assets such as JavaScript and CSS
config/ contains backend configurations
controllers/ contains Web controller classes
models/ contains backend-specific model classes
runtime/ contains files generated during runtime
tests/ contains tests for backend application
views/ contains view files for the Web application
web/ contains the entry script and Web resources
frontend
assets/ contains application assets such as JavaScript and CSS
config/ contains frontend configurations
controllers/ contains Web controller classes
models/ contains frontend-specific model classes
runtime/ contains files generated during runtime
tests/ contains tests for frontend application
views/ contains view files for the Web application
web/ contains the entry script and Web resources
widgets/ contains frontend widgets
api
assets/ contains application assets such as JavaScript and CSS
config/ contains api configurations
controllers/ contains Web controller classes
models/ contains api-specific model classes
runtime/ contains files generated during runtime
tests/ contains tests for api application
views/ contains view files for the Web application
web/ contains the entry script and Web resources
widgets/ contains api widgets
vendor/ contains dependent 3rd-party packages
environments/ contains environment-based overrides
```
31. Test the installation using Vagrant to see whether it supports api. Reference URL: https://github.com/yiisoft/yii2-app-advanced/blob/master/docs/guide-zh-CN/start-installation.md , install using Vagrant (manual for Windows users)
32. Go to the /vagrant/config folder, rename vagrant-local.example.yml to vagrant-local.yml (copying is recommended), and place your GitHub personal API token into vagrant-local.yml, as shown in Figure 23

33. Add the following code to the hosts file
# github-shuijingwan-yii2-app-advanced Vagrant
192.168.83.137 y2aa-frontend.test y2aa-backend.test y2aa-api.test
34. Open Windows PowerShell, switch the path to the project root directory, and execute the following command (requires a VPN/proxy and may need to be run multiple times). If an error occurs during the process, refer to step 15 for handling, as shown in Figure 24 and Figure 25


vagrant plugin install vagrant-hostmanager
vagrant up
35. After waiting for completion, access the following URLs in your browser; they work as expected, as shown in Figure 26
frontend: http://y2aa-frontend.test
backend: http://y2aa-backend.test
api: http://y2aa-api.test

36. Revert the changes made in step 32, and edit \vagrant\config\.gitignore
# local configuration
vagrant-local.yml


评论
一条对“Create a GitHub Repository for yiisoft/yii2-app-advanced and Add a RESTful API Application”的回复
[…] Based on yiisoft/yii2-app-advanced, create a new repository yii2-app-advanced on github, and create … […]