BX PHP 框架 - 开发包

维护者

详细信息

github.com/jarick/bx

主页

源代码

问题

安装: 1

依赖: 0

建议者: 0

安全: 0

星标: 1

关注者: 2

分支: 0

开放问题: 0

类型:bx-extension

dev-master 2014-07-21 22:26 UTC

This package is not auto-updated.

Last update: 2024-09-28 15:34:14 UTC


README

总体架构。

运行需要 PHP 版本 5.4 或更高版本,memcache(在没有网站的情况下,网站不会使用缓存),mysql 或 sqlite。
编码标准。

框架完全基于标准 psr。除了使用缩进的规则(使用缩进而不是空格)外。

结构。

代码位于 src 文件夹中,并分解为独立组件。组件结构分为 4 个业务层

  • 模型(Entity)是一个简单类,继承自接口 IEntity 并使用特质 EntityTrait

labels 函数中列出字段名称。示例

	protected function labels()
	{
		return [
			self::C_ID		 => $this->trans('user.entity.user.id'),
			self::C_UNIQUE_ID	 => $this->trans('user.entity.user.unique_id'),
			self::C_LOGIN		 => $this->trans('user.entity.user.login'),
			self::C_PASSWORD	 => $this->trans('user.entity.user.password'),
			self::C_EMAIL		 => $this->trans('user.entity.user.email'),
			self::C_CODE		 => $this->trans('user.entity.user.code'),
			self::C_CREATE_DATE	 => $this->trans('user.entity.user.create_date'),
			self::C_TIMESTAMP_X	 => $this->trans('user.entity.user.timestamp_x'),
			self::C_REGISTERED	 => $this->trans('user.entity.user.registered'),
			self::C_ACTIVE		 => $this->trans('user.entity.user.active'),
			self::C_DISPLAY_NAME => $this->trans('user.entity.user.display_name'),
		];
	}

rules 函数中列出字段验证规则。示例

	protected function rules()
	{
		return [
			[self::C_LOGIN,self::C_EMAIL],
			$this->rule()->string()->notEmpty()->setMax(50),
			[self::C_PASSWORD],
			$this->rule()->custom([$this,'filterPassword'])->notEmpty(),
			[self::C_CODE],
			$this->rule()->setter()->setFunction([$this,'filterCode'])->setValidators([
				$this->rule()->string()->notEmpty()->setMax(50),
			]),
			[self::C_CREATE_DATE],
			$this->rule()->setter()->setValidators([
				$this->rule()->datetime()->withTime()->notEmpty()
			])->setValue($this->date()->convertTimeStamp())->onAdd(),
			[self::C_TIMESTAMP_X],
			$this->rule()->setter()->setValidators([
				$this->rule()->datetime()->withTime()->notEmpty()
			])->setValue($this->date()->convertTimeStamp())->onAdd(),
			[self::C_DISPLAY_NAME],
			$this->rule()->string()->setMax(100),
			[self::C_REGISTERED,self::C_ACTIVE],
			$this->rule()->boolean(),
		];
	}

规则列表按顺序排列。首先指定字段集,然后指定这些字段的验证规则。可以为单个字段指定任意数量的规则。在验证字段时,首先应用数组中的早期元素,如果验证器返回错误,则不会应用该字段的后续验证器。

可以使用函数 $this->rule()->custom 设置字段的自定义过滤器和验证器。示例

	public function filterPassword(&$value)
	{
		if ($this->string()->length($value) === 0){
			return $this->trans('user.entity.user.error_password_empty');
		}
		$min = $this->getMinLengthPassword();
		if ($this->string()->length($value) < $min){
			return $this->trans('user.entity.user.error_password_min',['#MIN#' => $min]);
		}
		$value = password_hash($value,PASSWORD_BCRYPT);
	}
	public function filterCode(&$value)
	{
		$value = $this->string()->substr($this->string()->getSlug($this->getValue(self::C_LOGIN)),0,50);
	}

如示例所示,要更改字段输入的值,需要更改 $value 变量。要生成错误,需要返回包含错误的字符串。如果验证成功,则可以不返回任何内容或返回 null。

Entity 封装了字段值、字段名称、验证器和验证错误。要为实体设置值,请将包含值的数组传递给函数 setData

要验证传递的值,请执行函数 checkFields。要获取验证错误,请调用函数 getErrors

  • 数据存储层(Store)。在此层中描述了与不同数据库实体(Entity)交互的逻辑。例如,用户会话可以存储在 PHP 会话中、数据库中或 NoSql 存储中。在这种情况下,业务逻辑不必知道使用的是哪种存储。它将使用统一接口和相同的实体与所有存储进行交互。

存储数据的方式在类 BX\Base\Registry 中设置。如果没有指定存储机制,框架会自动选择最佳存储方法。

实际项目配置示例

	sites:
	    ###:
	        title: '###'
	        keywords: '###'
	        charset: UTF-8
	        name: ###
	        regex:
	            - ###.com
	            - localhost
	        folder: /
	        layout_rule:
	            ###:
	                - ""
	            admin:
	                - admin\/
	        url_rewrite:
	            console: /console/
	            news: /news/
	            admin: /admin/
	lang: ru
	date:
	    timezone: Europe/Kaliningrad
	mode: production
	templating:
	    engine: haml
	    haml: ~/../haml
	    php: ~/../cache
	    doc_root: ~/../www
	cache:
	    type: memcache
	    host: localhost
	    post: 11211
	pdo:
	    dsn: 'sqlite:../db.db'
	zend_search:
	    morphy_dicts: ~/../search/dicts
	    stop_words: ~/../search/stop-words/stop-words-ru.txt
	    index: ~/../search/data
	user:
	    password_min_length: 6

配置可以以 php array 或 yaml 格式指定,请参阅 Registry::init 函数的第二个参数。

  • 数据管理层(Manager)。这是包含所有数据交互逻辑的主要层。通常,在将对象实例存储在 ioc 存储库(请参阅 BX\Base\DI 类)的特质中隐藏对管理器的调用。在自己的逻辑中,始终可以重定义标准管理器。示例
	function it_clearCache(CacheManager $cache)
	{
		$cache->clearByTags('test')->shouldBeCalled()->willReturn(null);
		DICService::update('cache',$cache->getWrappedObject());
		$this->clearCache();
		DICService::update('cache',null);
	}

在此示例中,我们重定义了标准管理器为我们的 Mock 类,以检查 clearCache 函数的正确性。然后我们清除了容器,以便框架继续使用默认的管理器缓存。

  • 表示层(Widget)。类继承自 BX\MVC\Widget 类。应包含尽可能少的业务逻辑。用作代理类,以获取请求参数并将它们传递给数据管理层(Manager)。示例
	class CaptchaWidget extends Widget
	{
		use \BX\Translate\TranslateTrait;
		public function run()
		{
			$this->view->buffer()->flush();
			try{
				$ip = $this->request()->server()->get('REMOTE_ADDR');
				$cpt = new CaptchaManager($ip);
				if ($this->request()->query()->has('reload')){
					$cpt->reload();
				}
				$builder = new CaptchaRender($cpt->getEntity()->code);
				$this->response()->headers['Content-type'] = 'image/jpeg';
				$builder->output();
			}catch (\Exception $e){
				$this->log('captcha.widget.captcha')->err($e);
				echo $this->trans('captcha.widget.captcha.error_generate_captcha');
			}
			$this->view->abort();
		}
	}
从数据库中选择值。

ORM 框架使用 UnitOfWork 模式编写,并确保防止 Race condition。示例更改数据

	/**
	 * Clear old captcha
	 * @param integer $day
	 * @return boolean
	 * @throws \RuntimeException
	 */
	public function clear($day = 30)
	{
		$repository = new Repository('captcha');
		$time = $this->date()->convertTimeStamp(time() - $day * 3600 * 24);
		$captches = static::finder(CaptchaEntity::getClass())
			->filter(['<TIMESTAMP_X' => $time])
			->all();
		foreach($captches as $captcha){
			$repository->delete($this,$captcha);
		}
		if (!$repository->commit()){
			$mess = print_r($repository->getErrorEntity()->getErrors()->all(),1);
			throw new \RuntimeException('Error clear old captches. Error:'.$mess);
		}
		return true;
	}

在本例中,我们从数据库中删除所有旧的验证码哈希记录。要开始更改,需要创建一个 Repository 类的实例。添加操作通过 add 函数执行,更新操作通过 update 函数执行,删除操作通过 delete 函数执行。要使更改生效,需要调用 commit 函数。如果发生错误,它将返回 false

要执行过滤,需要调用函数 BX\DB\TableTrait::finder(参见 BX\DB\Filter\SqlBuilder 类)。

索引文件示例。
	<?php
	require dirname(__DIR__).'/vendor/autoload.php';
	BX\Config\Config::init('yaml_file',dirname(__DIR__).'/config/main.yml');
	BX\MVC\SiteController::run()->end();