The Clean Architecture in PHP 读书笔记(十)
laravel
这是clean architecture的第十篇,也是具体案例的第二篇,本篇会通过使用laravel框架,来开发我们的应用。
本文为系列文章的第十篇,完成的目录请查看Clean Architecture。
laravel的建立
composer create-project laravel/laravel --prefer-dist cleanphp-laravel
配置数据库采用sqlite,修改.env文件
DB_CONNECTION=sqlite
DB_DATABASE=/Users/zhuanxu/workspace/cleanphp-laravel/database/database.sqlite
此处DB_DATABASE换为你自己的路径,并新建database.sqlite,touch /Users/zhuanxu/workspace/cleanphp-laravel/database/database.sqlite
我们啊来建立我们的数据库sqlite3 database/database.sqlite
,建表,插入数据。
CREATE TABLE customers ( id integer PRIMARY KEY, name varchar(100) NOT NULL, email varchar(100) NOT NULL );
CREATE TABLE orders ( id integer PRIMARY KEY, customer_id int REFERENCES customers(id) NOT NULL, order_number varchar(20) NOT NULL, description text NOT NULL, total float NOT NULL );
CREATE TABLE invoices ( id integer PRIMARY KEY, order_id int REFERENCES orders(id) NOT NULL, invoice_date date NOT NULL, total float NOT NULL );
INSERT INTO customers(name, email) VALUES('Acme Corp', 'ap@acme.com'); INSERT INTO customers(name, email) VALUES('ABC Company', 'invoices@abc.com');
建立Dashboard
我们通过命令
php artisan make:controller DashboardController
来新建控制器,并修改routes/web.php
来设置路由
Route::get('/',"DashboardController@index");
而控制器文件里面的内容是:
namespace AppHttpControllers;
class DashboardController extends Controller
{
public function index()
{
return view("dashboard");
}
}
此处我们再新建resources/views/dashboard.blade.php,填充好内容后,我们就可以通过php artisan serve
来访问了
具体代码查看
git clone https://github.com/zhuanxuhit/php-clean-code.git
git checkout 15-laravel-dashboard
Customer管理
我们接着设置Customer的路由
Route::get( '/customers', 'CustomersController@index' );
Route::get( '/customers/new', 'CustomersController@edit' );
Route::post('/customers/new','CustomersController@store');
Route::get( '/customers/edit/{id}', 'CustomersController@edit' );
Route::post('/customers/edit/{id}','CustomersController@store');
然后控制器CustomersController
中注入CustomerRepositoryInterface
,
class CustomersController extends Controller
{
/**
* @var CleanPhpInvoicerDomainRepositoryCustomerRepositoryInterface
*/
private $customerRepository;
/**
* CustomersController constructor.
*
* @param CleanPhpInvoicerDomainRepositoryCustomerRepositoryInterface $customerRepository
*/
public function __construct(CustomerRepositoryInterface $customerRepository)
{
$this->customerRepository = $customerRepository;
}
}
通过Laravel的service container,能很方便的注入进来,此处我们需要声明CustomerRepositoryInterface
的实现,需要在文件app/Providers/AppServiceProvider.php
中新增:
use CleanPhpInvoicerPersistenceEloquentRepositoryCustomerRepository;
use CleanPhpInvoicerDomainRepositoryCustomerRepositoryInterface;
public function register()
{
$this->app->bind(CustomerRepositoryInterface::class,
CustomerRepository::class);
}
此处CustomerRepository
是持久层的基于Laravel的Eloquent的实现,Eloquent是Active Record的ORM,具体介绍可以看eloquent。
下面我们来实现具体Customer的操作。
Customer Listing
在CustomersController中新增index方法
public function index( )
{
$customers = $this->customerRepository->getAll();
return view('customers/index', ['customers' => $customers]);
}
并新增文件resources/views/customers/index.blade.php
Adding and Editing Customers
此处我们需要根据/customers/new
是get还是post方法来判断是新建一个customer还是进行修改。
此处我们需要几个功能
- form filter,我们需要对post的表单进行验证
- Hydrator,我们需要将输入的表单方便的赋值到我们的Entity的属性上
此处表单验证上,我们使用laravel的表单验证,不再自己开发了,通过命令php artisan make:request NewCustomerPost
新建。
public function rules()
{
return [
'name' => 'required',
'email' => 'required|email',
];
}
然后去controller中实现方法,
public function store(NewCustomerPost $request, $id = '')
{
$data = $request->all();
$customer = $id ? $this->customerRepository->getById($id) : new Customer();
$customer->setName($data['name'])->setEmail($data['email']);
$this->customerRepository->persist($customer);
return new RedirectResponse('/customers/edit/' . $customer->getId());
}
public function edit($id = '')
{
$customer = $id ? $this->customerRepository->getById($id) : new Customer();
$viewModel['customer'] = $customer;
return view('customers/new-or-edit', $viewModel);
}
我们可以看到controller里的方法都非常的薄,主要还是通过domain层来完成具体的操作。
具体代码查看
git clone https://github.com/zhuanxuhit/php-clean-code.git
git checkout 16-laravel-customers
Order管理
order总的过程和Customer类似,一个不同的地方是,Order里面有个属性是Customer,Order和Customer的关系是1对1,这在实现OrderRepository
需要注意了,里面从数据库转换后要进行转换,看代码:
/**
* @param $object
* @param Order $entity
*/
protected function hydrate( $object, $entity )
{
$customer = $this->customerRepository->getById($object->customer_id);
$entity->setCustomer($customer)->setOrderNumber($object->order_number)
->setTotal($object->total)->setDescription($object->description);
}
此处hydrate的作用是将数据库里的数据正确设置到Order对象$entity上。
具体代码查看
git clone https://github.com/zhuanxuhit/php-clean-code.git
git checkout 17-laravel-orders
invoice管理
invoice和之前的customer和order类似,需要注意的是invoice会有一个领域服务InvoicingService
,实现未出账单的出账操作。
/**
* @return array
*/
public function generateInvoices()
{
$orders = $this->orderRepository->getUninvoicedOrders();
$invoices = [];
foreach ($orders as $order){
$invoices[] = $this->factory->createFromOrder($order);
}
return $invoices;
}
除此之外就没什么需要注意的。
具体代码查看
git clone https://github.com/zhuanxuhit/php-clean-code.git
git checkout 18-laravel-invoices
以上就是php-clean-architecture的全部。
总结
The Clean Architecture in PHP读书笔记写到这全部结束了,在这最后一篇中,我们以laravel为框架给出了示例,最核心的领域逻辑是纯的php class,不依赖于任何的框架,我们可以快速的进行切换。
但是在使用laravel过程中,特别是repository这块,由于没有直接使用laravel的Eloquent模块,实现上确实比较麻烦,在实现CleanPhpInvoicerPersistenceEloquentRepository
下的类的时候,很多方法都比较tricky,而且可以想象的是,随着项目负责度的提升,这一块会成为程序员的梦靥,所以下一个系列我会去带领大家看看php中几大主流orm的实现原理,包括laravel,doctrine2,尽情期待。
这是The Clean Architecture in PHP的第十篇,你的鼓励是我继续写下去的动力,期待我们共同进步。
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(30)-本地化(多语言)
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(29)-T4模版
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(28)-系统小结
- 用谷歌浏览器来当手机模拟器
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(27)-权限管理系统-分配用户给角色
- ASP.NET MVC5+EF6+EasyUI 后台管理系统-分配角色给用户
- 体验vs11 Beta
- 构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(25)-权限管理系统-系统管理员(附生成器)
- 构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(24)-权限管理系统-将权限授权给角色
- 构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(23)-权限管理系统-角色组模块
- jQuery Gallery Plugin在Asp.Net中使用
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(22)-权限管理系统-模块导航制作
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(20)-权限管理系统-根据权限获取菜单
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(19)-权限管理系统-用户登录
- php概述
- php教程
- php环境搭建
- PHP书写格式
- php变量
- php常量
- PHP注释
- php数组
- php字符串 string
- PHP整型 integer
- PHP浮点型 float
- php布尔型
- php数据类型之数组
- php数据类型之对象
- php数据类型之null
- php数据类型之间的转换
- php运算符
- php表达式
- PHP循环控制
- PHP流程控制
- php函数
- php全局变量
- PHP魔术变量
- php命名空间
- php 日期
- PHP包含文件
- php文件
- PHP 文件上传
- php Cookies
- php Sessions
- php email
- php安全email
- php错误处理
- PHP异常处理
- php过滤器
- PHP 高级过滤器
- php json
- php 表单
- PHP MySQL 简介
- PHP 连接 MySQL
- php创建数据库
- php 创建表
- php mysq 插入数据
- PHP MySQL 插入多条数据
- PHP MySQL 预处理语句
- php mysql 读取数据
- php mysql where
- PHP MySQL Order By
- PHP MySQL Update
- PHP MySQL Delete
- php ODBC