overtrue / yaf-skeleton
该包已被废弃,不再维护。未建议替代包。
Yaf 框架的骨架。
1.1.1
2018-07-18 07:39 UTC
Requires
- php: >=7.0
- ext-yaf: *
- monolog/monolog: ~1.0
- psr/container: ^1.0
- psr/http-message: ~1.0
- symfony/console: 3.*
Requires (Dev)
- filp/whoops: ~2.1@stable
- friendsofphp/php-cs-fixer: ~1.8@stable
- mockery/mockery: ~1.0
- overtrue/phplint: dev-master
- phpmd/phpmd: ~2.6@stable
- phpunit/phpunit: ~6.0
- sebastian/phpcpd: ~2.0@stable
- sebastian/phpdcd: ~1.0@stable
- squizlabs/php_codesniffer: 3.0.x-dev
- symfony/var-dumper: ~3.0
Suggests
- league/plates: Plates is a native PHP template system that's fast, easy to use and easy to extend.
This package is auto-updated.
Last update: 2022-07-29 01:48:30 UTC
README
支持 Yaf 框架的测试性骨架和 composer。
要求
- PHP >= 7.0
- Yaf >= 3.0
安装
- 更新
yaf.ini
[yaf]
yaf.use_namespace=1
yaf.use_spl_autoload=1
...
- 创建项目。
$ composer create-project overtrue/yaf-skeleton myapp -vvv
-
Web 服务器重写规则
Apache
#.htaccess RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-f RewriteRule .* index.php
Nginx
server { listen 80; server_name myapp.com; root /path/to/myapp; index index.php index.html index.htm; if (!-e $request_filename) { rewrite ^/(.*) /index.php/$1 last; } }
Lighttpd
$HTTP["host"] =~ "(www.)?myapp.com$" { url.rewrite = ( "^/(.+)/?$" => "/index.php/$1", ) }
应用程序结构
├── .scripts
│ ├── .gitkeep
│ ├── common.sh
│ ├── job_phpcs.sh
│ ├── job_phpmd.sh
│ ├── job_phpunit.sh
│ ├── sami.phar
│ └── sami.php
├── app
│ ├── commands # sora commands (namespace:\App\Commands)
│ ├── controllers # Yaf Controllers (namespace:\)
│ ├── exceptions # Exceptions (namespace:\App\Exceptions)
│ ├── facades # Service Facades (namespace:\)
│ ├── plugins # Yaf plugins (namespace:\)
│ ├── presenters # Object presenters (namespace:\App\Presenters)
│ ├── services # Services, the 3rd service bridges (namespace:\App\Services)
│ ├── traits # Traits (namespace:\App\Traits)
│ ├── views # Template files
│ ├── helpers.php # Herlpers
│ ├── Bootstrap.php # Yaf Bootstrap file
├── config
│ ├── application.ini # Yaf config file
├── public # web extrence
│ └── index.php
├── sora # The command line tool
├── tests # Unit tests
└── vendor #
├── phpunit.xml.dist # PHPUnit config file
├── .gitignore
├── .php_cs # PHP-CS-Fixer config file
├── composer.json
├── composer.lock
├── README.md
控制器
$ ./sora make:controller Foo_Bar # or:foo_bar/FooBar/FooBarController # # /www/myapp/app/controllers/Foo/Bar.php Created! # /www/myapp/tests/controllers/Foo/BarTest.php Created!
所有控制器都创建在 app/controllers
目录中,测试文件也创建在 tests/controllers
目录中。
当然,您也可以独立创建测试:
$ ./sora make:test Foo_Bar # Also supports multiple type controller names # /www/myapp/tests/controllers/Foo/BarTest.php Created!
handle() 方法
控制器入口方法 handle()
<?php class ExampleController extends BaseController { public function handle() { return 'Hello world!'; // return json(['foo' => 'bar']); // return redirect('https://easywechat.com'); // return view('welcome', ['name' => 'MyApp']); // template engine require. } }
视图
没有内置的模板引擎。如果您需要使用 PHP 模板,我们推荐使用 Plates,Plates 是一个快速、易于使用且易于扩展的本地 PHP 模板系统。
$ composer require league/plates -vvv
您可以在控制器的 handle
方法中使用 view(string $template, array $data)
辅助函数作为结果。
例如
public function handle() { $data = [ 'name' => 'overtrue', 'age' => 28, ]; return view('profile-page', $data); }
<!--app/views/profile-page.php:--> <h1><?= $name ?></h1> <p><?= $age ?></p>
更多用法请参阅Plates 文档。
单元测试
编写单元测试的难度与代码质量成反比。代码质量越高,单元测试的难度越低,因此请设计好您的代码。
创建控制器的单元测试可以使用以下命令:
$ ./sora make:test Foo_BarController
编写测试用例
要创建控制器测试对象,使用 mock_controller
函数。
$controller = mock_controller(Foo_BarController::class); // Indicates the method to mock, and the protected method is also mockable $controller = mock_controller(Foo_BarController::class, ['getUsers', 'getApp']);
断言
我们有一个这样的控制器
... public function handle() { $params = Request::only('uids', 'screen_name', 'trim_status', 'has_extend', 'simplify', 'is_encoded'); $users = $this->get('main.users.show_batch', $params); return $users; } ...
因此测试应该涵盖上述三种行为:
public function testHandle() { $input = [ 'uids' => '2193182644', 'screen_name' => '安正超', 'trim_status' => 0, 'has_extend' => 1, 'simplify' => 0, 'is_encoded' => 0, 'foo' => 'bar', ]; Request::shouldReceive('only') ->with('uids', 'screen_name', 'trim_status', 'has_extend', 'simplify', 'is_encoded') ->andReturn($input); $controller = mock_controller(Users_Show_BatchController::class, ['get']); // mock the `get` method $controller->shouldReceive('get')->with('main.users.show_batch', array_except($_GET, ['foo'])) ->andReturn('foo') ->once(); $response = $controller->handle(); $this->assertSame('foo', $response); }
外观断言
Request::shouldReceive('get')->with('mid')->andReturn('mock-mid')->once(); Log::shouldReceive('action')->with(48, 'oid', 'ext')->once(); ..
内置辅助断言方法
$this->shouldAbort($message, $code);
它们用于对应控制器中 abort($message, $code);
抛出的异常
测试用例类中的某些辅助方法
模拟请求方法:
$this->method('post');
模拟请求 uri
:
$this->uri('/foo/bar?uid=12345');
模拟配置:
$this->config('foo', 'bar');
模拟请求 IP:
$this->ip('127.0.0.1');
模拟 $_SERVER 变量:
$this->server('REQUEST_URI', '/foo/bar');
文档
- Yaf 文档:https://php.ac.cn/manual/en/book.yaf.php
- Plates 文档:http://platesphp.com/v3/
- PHPUnit 文档:https://phpunit.de/manual/current/zh_cn/phpunit-book.html
- Mockery 文档:http://docs.mockery.io/en/latest/
❤️ 赞助我
如果你喜欢我的项目并想支持它,点击这里 ❤️
由 JetBrains 支持的项目
非常感谢 Jetbrains 慷慨提供许可证,让我能够为这个和其他开源项目工作。
PHP 扩展包开发
想知道如何从零开始构建 PHP 扩展包?
请关注我的实战课程,我会在此课程中分享一些扩展开发经验 —— 《PHP 扩展包实战教程 - 从入门到发布》
许可协议
MIT