没有不值得去解决的问题,也没有不值得去学习的技术!

基于 yiisoft/yii2-app-advanced,在 GitHub 上新建仓库 yii2-app-advanced,新建远程过程调用应用(实现基于 Hprose 2.0 for PHP 的 RPC 服务端),新建 rpc 目录、配置和环境、测试、Vagrant等的支持

打开 Windows PowerShell,执行 init 命令并选择 dev 作为环境,api应用所需环境配置文件自动生成

Yii2 Advanced 实战系列:RESTful API + RPC 服务 + 国际化 + 日志与测试

新建 api 目录、配置和环境、测试、Vagrant 等的支持。

(1) 基于 yiisoft/yii2-app-advanced,在 GitHub 上新建仓库 yii2-app-advanced,新建接口应用(实现 RESTful 风格的 Web Service 服务的 API),新建api目录、配置和环境、测试、Vagrant等的支持

(2) 基于 yiisoft/yii2-app-advanced,在 GitHub 上新建仓库 yii2-app-advanced,新建接口应用(实现 RESTful 风格的 Web Service 服务的 API),实现模型分层:数据层、逻辑层,明确公共目录、应用、模块的继承、引用关系

在 Postman 中,GET http://api.github-shuijingwan-yii2-app-advanced.localhost/v1/users ,200响应,message为简体中文

(3) 基于 yiisoft/yii2-app-advanced,在 GitHub 上新建仓库 yii2-app-advanced,新建接口应用(实现 RESTful 风格的 Web Service 服务的 API),实现 RESTful Web 服务,支持国际化(动态地设置目标语言,默认为简体中文)

运行测试,获取详细的输出,可看到一步一步的行为报告,符合预期

(4) 基于 yiisoft/yii2-app-advanced,在 GitHub 上新建仓库 yii2-app-advanced,新建接口应用(实现 RESTful 风格的 Web Service 服务的 API),在 api 的 tests 目录中准备用户相关操作的一些自动化测试的样例(API 测试),确保应用程序在改变或增加新的功能时不会影响现有的功能

在 Postman 中,GET http://api.github-shuijingwan-yii2-app-advanced.localhost/v1/logs?filter[level]=4&filter[category][like]=api\behaviors\RequestLogBehavior&filter[prefix][like]=app-api&filter[log_time][gte]=1528090828&filter[log_time][lte]=1529564924.6648 ,200响应,空数组已经被自动转换为空对象,以保证字段格式的统一,GET http://api.github-shuijingwan-yii2-app-advanced.localhost/v1/logs/3

(5) 基于 yiisoft/yii2-app-advanced,在 GitHub 上新建仓库 yii2-app-advanced,新建接口应用(实现 RESTful 风格的 Web Service 服务的 API),调整默认字符集为:utf8mb4,接口响应格式的调整,空数组自动转换为空对象,在接口应用中收集请求日志消息(1个请求对应1条日志消息)至数据库,且实现日志功能的相应接口:日志列表(设置数据过滤器以启用筛选器处理)、日志详情

在开发环境中,执行数据库迁移命令失败:1071 Specified key was too long; max key length is 767 bytes

(6) 基于 yiisoft/yii2-app-advanced,在 GitHub 上新建仓库 yii2-app-advanced,新建接口应用(实现 RESTful 风格的 Web Service 服务的 API),调整默认字符集为:utf8mb4,接口响应格式的调整,空数组自动转换为空对象,在接口应用中收集请求日志消息(1个请求对应1条日志消息)至数据库,且实现日志功能的相应接口:日志列表(设置数据过滤器以启用筛选器处理)、日志详情(二)

浏览 user 表数据,status、updated_at 已经更新

(7) 基于 yiisoft/yii2-app-advanced,在 GitHub 上新建仓库 yii2-app-advanced,新建接口应用(实现 RESTful 风格的 Web Service 服务的 API),实现 ActiveRecord 的软删除,生成 ActiveQuery,自定义查询类

执行数据库迁移命令,查看数据库表 user 结构,符合预期

(8) 基于 yiisoft/yii2-app-advanced,在 GitHub 上新建仓库 yii2-app-advanced,新建接口应用(实现 RESTful 风格的 Web Service 服务的 API),实现 ActiveRecord 的软删除,生成 ActiveQuery,自定义查询类(二)

在 Postman 中 POST 请求,http://api.github-shuijingwan-yii2-app-advanced.localhost/v1/users ,输入格式:application/json

(9) 基于 yiisoft/yii2-app-advanced,在 GitHub 上新建仓库 yii2-app-advanced,新建接口应用(实现 RESTful 风格的 Web Service 服务的 API),application/x-www-form-urlencoded 和 multipart/form-data 输入格式,默认支持,新增 application/json 输入格式的支持

打开 Windows PowerShell,执行 init 命令并选择 dev 作为环境,api应用所需环境配置文件自动生成

(10) 基于 yiisoft/yii2-app-advanced,在 GitHub 上新建仓库 yii2-app-advanced,新建远程过程调用应用(实现基于 Hprose 2.0 for PHP 的 RPC 服务端),新建 rpc 目录、配置和环境、测试、Vagrant等的支持

出现以上原因是因为 Windows 下 nginx php 环境,不支持并发的原因,当同时访问多个域名,并且同时指向你本地服务的时候,就不支持并发了。nginx.conf 里面 对不同 server 修改 fastcgi_pass 的端口号,启动多个 php-cgi。

(11) 基于 yiisoft/yii2-app-advanced,在 GitHub 上新建仓库 yii2-app-advanced,新建远程过程调用应用(实现基于 Hprose 2.0 for PHP 的 RPC 服务端),在 rpc 目录中实现 页面 的相应 RPC 服务,且在 api 目录中的 API 实现 RPC 客户端

执行数据库迁移,查看表结构,基于 Gii 重新生成模型文件

(12) 基于 yiisoft/yii2-app-advanced,在 GitHub 上新建仓库 yii2-app-advanced,UUID 的实现

由于日志消息是存储于 MySQL 的 log 表中,在生产环境中,累积了大量的数据,log 表的数据长度已经达到 数百 GB ,因此,决定基于控制台命令行实现日志消息的定时删除,开发环境的 log 表的数据长度为 14.64 GB

(13) 基于 yiisoft/yii2-app-advanced,在 GitHub 上新建仓库 yii2-app-advanced,日志消息的自动定时删除

1、在 api 目录中实现 页面 的相应 RESTful 风格的 Web Service 服务的 API,然后再调整为 RPC 客户端

2、页面 的相应 API 全部实现后,在 Postman 中执行 POST 请求,响应正常,如图1

页面 的相应 API 全部实现后,在 Postman 中执行 POST 请求,响应正常
图1

{
	"title":"title-20180731-1",
	"body":"body-20180731-1"
}



{
    "code": 10000,
    "message": "创建页面成功",
    "data": {
        "title": "title-20180731-1",
        "body": "body-20180731-1",
        "slug": "title-20180731-1",
        "created_at": 1533015414,
        "updated_at": 1533015414,
        "id": 1
    }
}


3、在 Postman 中执行 PUT /pages/1 请求,响应正常


{
	"slug":"slug-20180731-1",
	"title":"title-20180731-1",
	"body":"body-20180731-1",
	"status":2
}



{
    "code": 10000,
    "message": "更新页面成功",
    "data": {
        "id": 1,
        "slug": "slug-20180731-1",
        "title": "title-20180731-1",
        "body": "body-20180731-1",
        "view": 0,
        "status": 2,
        "created_at": 1533015414,
        "updated_at": 1533015770
    }
}


4、在 Postman 中执行 GET /pages 请求,响应正常


{
    "code": 10000,
    "message": "获取页面列表成功",
    "data": {
        "items": [
            {
                "id": 1,
                "slug": "slug-20180731-1",
                "title": "title-20180731-1",
                "body": "body-20180731-1",
                "view": 0,
                "status": 2,
                "created_at": 1533015414,
                "updated_at": 1533015770
            }
        ],
        "_links": {
            "self": {
                "href": "http://api.github-shuijingwan-yii2-app-advanced.localhost/v1/pages?page=1"
            }
        },
        "_meta": {
            "totalCount": 1,
            "pageCount": 1,
            "currentPage": 1,
            "perPage": 20
        }
    }
}


5、在 Postman 中执行 GET /pages/1 请求,响应正常


{
    "code": 10000,
    "message": "获取用户详情成功",
    "data": {
        "id": 1,
        "slug": "slug-20180731-1",
        "title": "title-20180731-1",
        "body": "body-20180731-1",
        "view": 0,
        "status": 2,
        "created_at": 1533015414,
        "updated_at": 1533015770
    }
}


6、在 Postman 中执行 DELETE /pages/1 请求,响应正常


{
    "code": 10000,
    "message": "删除页面成功"
}


7、在 Postman 中执行 GET /pages 请求,响应正常


filter[title][like]:title
filter[slug][like]:2018
filter[status]:2



{
    "code": 10000,
    "message": "获取页面列表成功",
    "data": {
        "items": [
            {
                "id": 1,
                "slug": "slug-20180731-1",
                "title": "title-20180731-1",
                "body": "body-20180731-1",
                "view": 0,
                "status": 2,
                "created_at": 1533015414,
                "updated_at": 1533019394
            }
        ],
        "_links": {
            "self": {
                "href": "http://api.github-shuijingwan-yii2-app-advanced.localhost/v1/pages?filter%5Btitle%5D%5Blike%5D=title&filter%5Bslug%5D%5Blike%5D=2018&filter%5Bstatus%5D=2&page=1"
            }
        },
        "_meta": {
            "totalCount": 1,
            "pageCount": 1,
            "currentPage": 1,
            "perPage": 20
        }
    }
}


8、使用 composer 命令行安装 Hprose


composer require "hprose/hprose-yii:^2.0"



./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 2 installs, 0 updates, 0 removals
  - Installing hprose/hprose (v2.0.35): Downloading (100%)
  - Installing hprose/hprose-yii (v2.0.0): Downloading (100%)
hprose/hprose suggests installing ext-hprose (Faster serialize and unserialize hprose extension.)
hprose/hprose-yii suggests installing ext-hprose (Faster serialize and unserialize hprose extension.)
Writing lock file
Generating autoload files


9、添加 RPC 应用程序(rpc),复制 frontend 至 rpc, environments/dev/frontend 至 environments/dev/rpc 以及 environments/prod/frontend 至 environments/prod/rpc

10、删除目录 \rpc\runtime\debug 下的所有文件,删除目录 \rpc\tests\_output 下除.gitignore之外的所有文件,删除 \rpc\runtime\logs\app.log,在目录 /rpc 中调整命名空间和路径以 rpc 开头(替换 frontend 为 rpc),如图2

删除目录 \rpc\runtime\debug 下的所有文件,删除目录 \rpc\tests\_output 下除.gitignore之外的所有文件,删除 \rpc\runtime\logs\app.log,在目录 /rpc 中调整命名空间和路径以 rpc 开头(替换 frontend 为 rpc)
图2

11、在 common\config\bootstrap.php 中添加 Yii::setAlias(‘rpc’, dirname(dirname(__DIR__)) . ‘/rpc’)

12、编辑environments/index.php,搜索此文件有6处frontend,则相应复制6份,替换为rpc

13、\vagrant\nginx\app.conf,新增虚拟主机 rpc

14、编辑 \vagrant\nginx\log\.gitignore,配置 rpc 的日志文件为忽略

15、编辑 \Vagrantfile,新增 rpc 相关的配置

16、基于 Nginx 配置 Web 服务器,配置虚拟主机:www、backend、api、rpc,编辑 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;
	}
}

## RPC ##
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 rpc.github-shuijingwan-yii2-app-advanced.localhost;
    root        E:/wwwroot/github-shuijingwan-yii2-app-advanced/rpc/web;
    index       index.php;

    access_log  logs/rpc.github-shuijingwan-yii2-app-advanced.localhost.access.log;
    error_log   logs/rpc.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;
}



17、打开 Windows PowerShell,执行 init 命令并选择 dev 作为环境,api应用所需环境配置文件自动生成,如图3

打开 Windows PowerShell,执行 init 命令并选择 dev 作为环境,api应用所需环境配置文件自动生成
图3

.\init
0
yes
All


18、打开:http://rpc.github-shuijingwan-yii2-app-advanced.localhost/ ,符合预期

19、编辑 codeception.yml 配置包含所有应用程序的测试

20、由于控制台应用程序使用不同的请求组件,因此编辑 \common\config\test.php,注释 request 组件(在 Web 应用程序中需取消注释)


    'components' => [
        'user' => [
            'class' => 'yii\web\User',
            'identityClass' => 'common\models\User',
        ],
        /*
        'request' => [
            'cookieValidationKey' => 'test',
        ],
        */
    ],


21、执行测试的迁移命令,如图4

执行测试的迁移命令
图4

./yii_test migrate --migrationPath=@yii/log/migrations/
./yii_test migrate


22、构建测试套件,然后运行所有的样例测试
注:执行迁移命令(./yii_test migrate)后,需取消注释 request 组件,否则报错:


 Test  ..\common\tests\unit\models\LoginFormTest.php:testLoginCorrect

  [yii\base\InvalidConfigException] yii\web\Request::cookieValidationKey must be configured with a secret key.



vendor/bin/codecept build
vendor/bin/codecept run


23、编辑 README.md,在目录结构中新增 rpc

<p align="center">
    <a href="https://github.com/yiisoft" target="_blank">
        <img src="https://avatars0.githubusercontent.com/u/993323" height="100px">
    </a>
    <h1 align="center">Yii 2 Advanced Project Template</h1>
    <br>
</p>
 
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 four tiers: api, 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-zh-CN/README.md](docs/guide-zh-CN/README.md).
 
[![Latest Stable Version](https://img.shields.io/packagist/v/yiisoft/yii2-app-advanced.svg)](https://packagist.org/packages/yiisoft/yii2-app-advanced)
[![Total Downloads](https://img.shields.io/packagist/dt/yiisoft/yii2-app-advanced.svg)](https://packagist.org/packages/yiisoft/yii2-app-advanced)
[![Build Status](https://travis-ci.org/yiisoft/yii2-app-advanced.svg?branch=master)](https://travis-ci.org/yiisoft/yii2-app-advanced)
 
## TABLE OF CONTENTS
- [Basic info](docs/guide-zh-CN/README.md)
- [Installation](docs/guide-zh-CN/start-installation.md)
    - [Manual installation](docs/guide-zh-CN/start-installation.md)
    - [Vagrant installation](docs/guide-zh-CN/start-installation.md#使用vagrant安装)
- [Testing](docs/guide-zh-CN/start-testing.md)
 
DIRECTORY STRUCTURE
-------------------
 
```
common
    config/              contains shared configurations
    fixtures/            contains fixtures for common classes
    logics/              contains logic classes used in both backend and frontend and api and console
    mail/                contains view files for e-mails
    messages/            contains message files for I18N
    models/              contains model classes used in both backend and frontend and api and console
    tests/               contains various tests for common classes
    widgets/             contains common widgets
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 various 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 various 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
    behaviors/           contains behaviors for api application
    config/              contains api configurations
    controllers/         contains Web controller classes
    fixtures/            contains fixtures for api application
    models/              contains api-specific model classes
    modules/             contains modules for api application
    rests/               contains rests for api application
    runtime/             contains files generated during runtime
    tests/               contains various tests for api application
    views/               contains view files for the Web application
    web/                 contains the entry script and Web resources
rpc
    assets/              contains application assets such as JavaScript and CSS
    config/              contains rpc configurations
    controllers/         contains Web controller classes
    models/              contains rpc-specific model classes
    runtime/             contains files generated during runtime
    tests/               contains various tests for rpc application
    views/               contains view files for the Web application
    web/                 contains the entry script and Web resources
    widgets/             contains rpc widgets
vendor/                  contains dependent 3rd-party packages
environments/            contains environment-based overrides
.gitignore               contains a list of directories ignored by git version system. If you need something never get to your source code repository, add it there.
composer.json            Composer config described in Configuring Composer.
init                     initialization script described in Configuration and environments.
init.bat                 same for Windows.
LICENSE.md               license info. Put your project license there. Especially when opensourcing.
README.md                basic info about installing template. Consider replacing it with information about your project and its installation.
requirements.php         Yii requirements checker.
yii                      console application bootstrap.
yii.bat                  same for Windows.
```
 
 

24、测试使用Vagrant安装,是否支持 rpc,参考网址:https://github.com/yiisoft/yii2-app-advanced/blob/master/docs/guide-zh-CN/start-installation.md ,使用Vagrant安装(Windows 用户手册)

25、编辑如下代码到 hosts 文件


# github-shuijingwan-yii2-app-advanced Vagrant
192.168.83.137 y2aa-frontend.test y2aa-backend.test y2aa-api.test y2aa-rpc.test


26、打开Windows PowerShell,切换路径至项目根目录,并且执行如下命令(需要翻墙,可能需要执行多次),期间有报错,参考第20步骤处理,报错:The name of your virtual machine couldn’t be set because VirtualBox
is reporting another VM with that name already exists. ,打开 VirtualBox,删除虚拟机 ubuntu-16.04-amd64_1533104831432_66987,删除目录 F:\VirtualBox VMs\ubuntu-16.04-amd64_1533105278434_57210


vagrant plugin install vagrant-hostmanager
vagrant up


27、等待完成后,在浏览器中访问如下URL即可,符合预期

frontend: http://y2aa-frontend.test
backend: http://y2aa-backend.test
api: http://y2aa-api.test
rpc: http://y2aa-rpc.test

基于 yiisoft/yii2-app-advanced,在 GitHub 上新建仓库 yii2-app-advanced,新建接口应用(实现 RESTful 风格的 Web Service 服务的 API),application/x-www-form-urlencoded 和 multipart/form-data 输入格式,默认支持,新增 application/json 输入格式的支持 基于 yiisoft/yii2-app-advanced,在 GitHub 上新建仓库 yii2-app-advanced,新建远程过程调用应用(实现基于 Hprose 2.0 for PHP 的 RPC 服务端),在 rpc 目录中实现 页面 的相应 RPC 服务,且在 api 目录中的 API 实现 RPC 客户端

PHP / Yii2 老项目维护与长期技术支持

如果你的 Yii2 项目已经上线,但遇到原开发离职、Bug 长期无人修复、接口不稳定、性能下降、代码难以接手等问题,可以联系我做一次远程技术排查。

适合以下情况:
✅ Yii2 老项目无人维护
✅ 后台管理系统 Bug 修复
✅ RESTful API 接口排查
✅ 小功能迭代与历史代码接手
✅ MySQL / Redis / Nginx 性能问题
✅ 长期远程兼职维护

可先从一次小问题开始:
✅ 线上报错排查
✅ 接口异常分析
✅ 慢查询与性能瓶颈定位
✅ 代码结构初步评估
✅ 部署环境与日志检查

如需咨询,请联系我,并注明:Yii2 维护咨询

联系方式:
Telegram:@shuijingwan
微信:13980074657
邮箱:shuijingwanwq@gmail.com

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理