# Edusoho
http://www.edusoho.com/
下载:http://dl.edusoho.com/edusoho-release/edusoho-8.3.1.tar.gz
git: https://gitee.com/webjust/Edusoho
## 目录结构
入口:{$HOME}\web\
控制器:{$HOME}\src\AppBundle\Controller\模块名Controller.php
模型:{$HOME}\src\Biz\Controller\模块名\Dao\Impl\表面DaoImpl.php
视图:{$HOME}\app\Resources\views\视图文件夹路径\名称.html.twig
路由文件:{$HOME}\api\config\routing.php
## 入口文件
{$HOME}\web\app.php
```
$kernel = new AppKernel('prod', false);
$kernel->loadClassCache();
$request = Request::createFromGlobals();
$kernel->setRequest($request);
$response = $kernel->handle($request);
$response->send();
$kernel->terminate($request, $response);
```
## 配置
//路由
{$HOME}\src\AppBundle\Resources\config\routing.yml
{$HOME}\src\AppBundle\Resources\config\routing_admin.yml
```
homepage:
path: /
defaults: { _controller: AppBundle:Default:index }
...
order_calculate_price:
path: /order/price/calculate
defaults: { _controller: AppBundle:Order/Order:price, limit: '' }
admin_discovery_column_category_tree:
path: /discovery_column/category/tree
defaults: { _controller: AppBundle:Admin/DiscoveryColumn:categoryTree }
```
## 控制器
{HOME}\src\AppBundle
以 http://edu.test/user/4 为例:
$app->get(_u('/user/{id}'), 'res.User:get');
**{$HOME}\src\AppBundle\Controller\UserController.php**
```
protected function tryGetUser($id)
{
$user = $this->getUserService()->getUser($id);
if (empty($user)) {
throw $this->createNotFoundException();
}
return $user;
}
```
## 服务层
以 http://edu.test/user/4/about 为例:
{HOME}\src\Biz\User\Service\UserService.php
**{$HOME}\src\AppBundle\Controller\UserController.php**
```
public function aboutAction(Request $request, $id)
{
$user = $this->tryGetUser($id);
return $this->_aboutAction($user);
}
protected function _aboutAction($user)
{
$userProfile = $this->getUserService()->getUserProfile($user['id']);
//不存在 getUserProfile() 方法时,则调用 get 方法,表为 user_profile
return $this->render('user/about.html.twig', array(
'user' => $user,
'userProfile' => $userProfile,
'type' => 'about',
));
}
```
**{$HOME}\src\Biz\User\Service\Impl\UserServiceImpl.php**
```
<?php
namespace Biz\User\Service\Impl;
use Biz\BaseService;
use Biz\User\Dao\UserDao;
...
class UserServiceImpl extends BaseService implements UserService{
public function getUser($id, $lock = false)
{
$user = $this->getUserDao()->get($id, array('lock' => $lock));
return !$user ? null : UserSerialize::unserialize($user);
}
...
public function getUserProfile($id)
{
return $this->getProfileDao()->get($id);
}
}
```
**{$HOME}\vendor\codeages\biz-framework\src\Dao\DaoProxy.php**
```
<?php
namespace Codeages\Biz\Framework\Dao;
use Codeages\Biz\Framework\Dao\Annotation\MetadataReader;
class DaoProxy
{
/**
* 代理 get 开头的方法调用
*
* @param string $method 被调用的 Dao 方法名
* @param array $arguments 调用参数
* @return array|null
*/
protected function get($method, $arguments)
{
$lastArgument = end($arguments);
reset($arguments);
// lock模式下,因为需要借助mysql的锁,不走cache
if (is_array($lastArgument) && isset($lastArgument['lock']) && true === $lastArgument['lock']) {
$row = $this->callRealDao($method, $arguments);
$this->unserialize($row);
return $row;
}
if ($this->arrayStorage) {
$key = $this->getCacheKey($this->dao, $method, $arguments);
if (!empty($this->arrayStorage[$key])) {
return $this->arrayStorage[$key];
}
}
$strategy = $this->buildCacheStrategy();
if ($strategy) {
$cache = $strategy->beforeQuery($this->dao, $method, $arguments);
// 命中 cache, 直接返回 cache 数据
if (false !== $cache) {
return $cache;
}
}
$row = $this->callRealDao($method, $arguments);
$this->unserialize($row);
// 将结果缓存至 ArrayStorage
$this->arrayStorage && ($this->arrayStorage[$this->getCacheKey($this->dao, $method, $arguments)] = $row);
if ($strategy) {
$strategy->afterQuery($this->dao, $method, $arguments, $row);
}
return $row;
}
}
```
## 模型
**{$HOME}\src\Biz\User\Dao\Impl\UserDaoImpl.php**
```
<?php
namespace Biz\User\Dao\Impl;
use Biz\User\Dao\UserDao;
use Codeages\Biz\Framework\Dao\AdvancedDaoImpl;
class UserDaoImpl extends AdvancedDaoImpl implements UserDao{
protected $table = 'user';
...
}
```
**{$HOME}\vendor\codeages\biz-framework\src\Dao\GeneralDaoImpl.php**
```
<?php
namespace Codeages\Biz\Framework\Dao;
use Codeages\Biz\Framework\Context\Biz;
abstract class GeneralDaoImpl implements GeneralDaoInterface{
...
public function get($id, array $options = array())
{
$lock = isset($options['lock']) && true === $options['lock'];
$sql = "SELECT * FROM {$this->table()} WHERE id = ?".($lock ? ' FOR UPDATE' : '');
return $this->db()->fetchAssoc($sql, array($id)) ?: null;
}
...
}
```