版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u014691098/article/details/80740219
phalcon除了可以设置不同模型连接不同的数据库还可以设置数据库读写分离。下面就说说怎么使用主从设置。
1、修改config下的配置文件(三种模式下的配置文件)
修改
'db' => [
// 是否记录执行的mysql语句
'logged' => true,
// 记录执行时间超过0秒的mysql语句
'max_execute_time' => 0,
// 比较时间到小数点后几位
'scale' => 5,
'log_path' => BASE_PATH . 'runtime/mysql/{Y/m/d}/{YmdH}.log',
// 使用动态更新
'use_dynamic_update' => true,
// ORM选项配置
'orm_options' => [
// 是否对字段是否为空的判断
'notNullValidations' => false
],
'master' => [
[
'host' => 'localhost',
'port' => 3306,
'username' => 'root',
'password' => '123456',
'dbname' => 'phalcon',
'charset' => 'utf8'
]
],
'slave' => [
[
'host' => 'localhost',
'port' => 3306,
'username' => 'root',
'password' => '123456',
'dbname' => 'phalcon',
'charset' => 'utf8'
]
]
],
完整的config/config_dev.php
<?php
/**
* @desc 全局配置文件
* @author zhaoyang
* @date 2018年5月3日 下午7:54:47
*/
return [
// 应用配置
'application' => [
'debug' => [
'state' => false,
'path' => BASE_PATH . 'runtime/debug/{YmdH}.log'
],
'error' => [
'path' => BASE_PATH . 'runtime/error/{YmdH}.log'
]
],
// 服务配置
'services' => [
// mysql数据库配置
'db' => [
// 是否记录执行的mysql语句
'logged' => true,
// 记录执行时间超过0秒的mysql语句
'max_execute_time' => 0,
// 比较时间到小数点后几位
'scale' => 5,
'log_path' => BASE_PATH . 'runtime/mysql/{Y/m/d}/{YmdH}.log',
// 使用动态更新
'use_dynamic_update' => true,
// ORM选项配置
'orm_options' => [
// 是否对字段是否为空的判断
'notNullValidations' => false
],
'master' => [
[
'host' => 'localhost',
'port' => 3306,
'username' => 'root',
'password' => '123456',
'dbname' => 'phalcon',
'charset' => 'utf8'
]
],
'slave' => [
[
'host' => 'localhost',
'port' => 3306,
'username' => 'root',
'password' => '123456',
'dbname' => 'phalcon',
'charset' => 'utf8'
]
]
],
// 调度器配置
'dispatcher' => [
// 处理 Not-Found错误配置
'notfound' => [
// 错误码及错误提示
'status_code' => 404,
'message' => 'Not Found',
// 错误跳转的页面
'namespace' => DEFAULT_MODULE_NAMESPACE . '\\Controllers',
'controller' => 'error',
'action' => 'error404'
]
],
// volt引擎相关配置
'view_engine_volt' => [
// 编译模板目录
'compiled_path' => BASE_PATH . 'runtime/' . DEFAULT_MODULE . '/compiled/volt' . DS,
// 是否实时编译
'compile_always' => false,
// 附加到已编译的PHP文件的扩展名
'compiled_extension' => '.php',
// 使用这个替换目录分隔符
'compiled_separator' => '%%',
// 是否要检查在模板文件和它的编译路径之间是否存在差异
'stat' => true,
// 模板前缀
'prefix' => '',
// 支持HTML的全局自动转义
'autoescape' => false
],
// 模板相关配置
'view' => [
// 模板后缀
'view_suffix' => 'volt,phtml',
// 模板路径
'view_path' => APP_PATH . DEFAULT_MODULE . '/views' . DS,
// 模板引擎,暂时支持viewEngineVolt or viewEnginePhp,与模板后缀一一对应
'view_service' => 'viewEngineVolt,viewEnginePhp',
'disable_level' => [
'level_action_view' => false,
'level_before_template' => true,
'level_layout' => true,
'level_after_template' => true,
'level_main_layout' => true
]
],
// 过滤器设置
'filter' => [
// 过滤类型,支持string、trim、absint、int、email、float、int!、float!、alphanum、striptags、lower、upper、url、special_chars
'default_filter' => 'string,trim'
],
// 文件日志,formatter常用line,adapter常用file
'logger' => [
'line' => [
'format' => '[%date%][%type%] %message%',
'date_format' => 'Y-m-d H:i:s'
],
'file' => [
'alert' => BASE_PATH . 'runtime/' . DEFAULT_MODULE . '/logs/alert/{Y/m/d}/{YmdH}.log',
'critical' => BASE_PATH . 'runtime/' . DEFAULT_MODULE . '/logs/critical/{Y/m/d}/{YmdH}.log',
'debug' => BASE_PATH . 'runtime/' . DEFAULT_MODULE . '/logs/debug/{Y/m/d}/{YmdH}.log',
'error' => BASE_PATH . 'runtime/' . DEFAULT_MODULE . '/logs/error/{Y/m/d}/{YmdH}.log',
'emergency' => BASE_PATH . 'runtime/' . DEFAULT_MODULE . '/logs/emergency/{Y/m/d}/{YmdH}.log',
'info' => BASE_PATH . 'runtime/' . DEFAULT_MODULE . '/logs/info/{Y/m/d}/{YmdH}.log',
'notice' => BASE_PATH . 'runtime/' . DEFAULT_MODULE . '/logs/notice/{Y/m/d}/{YmdH}.log',
'warning' => BASE_PATH . 'runtime/' . DEFAULT_MODULE . '/logs/warning/{Y/m/d}/{YmdH}.log'
]
],
// session配置
'session' => [
// 是否自动开启 SESSION
'auto_start' => true,
'options' => [
'adapter' => 'files',
'unique_id' => DEFAULT_MODULE
]
// @formatter:off
/* // phalcon提供了四种适配器,分别是files、memcache、redis、libmemcached
'options' => [
'adapter' => 'memcache',
'unique_id' => DEFAULT_MODULE,
'prefix' => DEFAULT_MODULE,
'persistent' => true,
'lifetime' => 3600
],
'options' => [
'adapter' => 'redis',
'unique_id' => DEFAULT_MODULE,
'prefix' => DEFAULT_MODULE,
'auth' => '',
'persistent' => false,
'lifetime' => 3600,
'index' => 1
] */
// @formatter:on
],
// 加密配置
'crypt' => [
// 加密秘钥
'key' => DEFAULT_MODULE,
// 填充方式,默认是0(PADDING_DEFAULT),1(PADDING_ANSI_X_923)、2(PADDING_PKCS7)、3(PADDING_ISO_10126)、4(PADDING_ISO_IEC_7816_4)、5(PADDING_ZERO)、6(PADDING_SPACE)
'padding' => '',
// 加密方法,默认是"aes-256-cfb"
'cipher' => ''
],
// cookies配置
'cookies' => [
// 是否使用加密,使用加密必须要设置crypt 的key值
'use_encryption' => true
],
// 缓存配置
'cache' => [
'frontend' => [
// 数据处理方式,支持data(序列化)、json、base64、none、output、igbinary、msgpack
'data' => [
'lifetime' => 172800
],
'output' => [
'lifetime' => 172800
]
],
'backend' => [
// 数据缓存方式,支持memcache、file、redis、mongo、apc、apcu、libmemcached、memory、xcache
'file' => [
'cache_dir' => BASE_PATH . 'runtime/' . DEFAULT_MODULE . '/cache/',
// 对保存的键名进行md5加密
'safekey' => true,
'prefix' => ''
],
'memcache' => [
'host' => 'localhost',
'port' => '11211',
'persistent' => false,
'prefix' => '',
// 默认情况下禁用对缓存键的跟踪
'stats_key' => ''
],
'redis' => [
'host' => '127.0.0.1',
'port' => 6379,
'auth' => '',
'persistent' => false,
'prefix' => '',
'stats_key' => '',
'index' => 0
]
]
],
// 模型元数据缓存配置
'models_metadata' => [
'options' => [
// 适配器,默认使用memory(内存),还支持apc、apcu、files、libmemcached、memcache、redis、session、xcache
'adapter' => 'files',
'meta_data_dir' => BASE_PATH . 'runtime/' . DEFAULT_MODULE . '/models_metadata/'
]
// @formatter:off
/* 'options' => [
'adapter' => 'files',
'meta_data_dir' => BASE_PATH . 'runtime/' . DEFAULT_MODULE . '/models_metadata/'
],
'options' => [
'adapter' => 'memcache',
'unique_id' => DEFAULT_MODULE,
'prefix' => DEFAULT_MODULE,
'persistent' => true,
'lifetime' => 3600
],
'options' => [
'adapter' => 'memory',
],
'options' => [
'adapter' => 'redis',
'unique_id' => DEFAULT_MODULE,
'prefix' => DEFAULT_MODULE,
'auth' => '',
'persistent' => false,
'lifetime' => 3600,
'index' => 1
],
'options' => [
'adapter' => 'session',
'prefix' => DEFAULT_MODULE,
] */
// @formatter:on
],
// 模型缓存配置
'models_cache' => [
'frontend' => [
'adapter' => 'data',
'lifetime' => 86400
],
'backend' => [
'adapter' => 'file',
'cache_dir' => BASE_PATH . 'runtime/' . DEFAULT_MODULE . '/models_cache/'
]
],
// 视图缓存配置
'view_cache' => [
'frontend' => [
'adapter' => 'output',
'lifetime' => 86400
],
'backend' => [
'adapter' => 'file',
'cache_dir' => BASE_PATH . 'runtime/' . DEFAULT_MODULE . '/cache/view/',
'prefix' => ''
]
],
// url配置
'url' => [
'base_uri' => '/',
'static_base_uri' => '/',
'base_path' => ''
],
'flash' => [
// 消息class属性值
'css_classes' => [
'error' => 'alert alert-danger',
'success' => 'alert alert-success',
'notice' => 'alert alert-info',
'warning' => 'alert alert-warning'
],
// 是否在生成的html中设置自动转义模式
'autoescape' => true,
// 是否必须使用HTML隐式格式化输出
'automatic_html' => true,
// 是否立即输出,为true时,调用$this->flash->message()或其他设置消息(例如success)时,消息立即输出(echo)
// 为false时,消息不会输出,会保存在flash对象中并返回消息$res = $this->flash->success('my message');
'implicit_flush' => false
],
'flash_session' => [
// 消息class属性值
'css_classes' => [
'error' => 'alert alert-danger',
'success' => 'alert alert-success',
'notice' => 'alert alert-info',
'warning' => 'alert alert-warning'
],
// 是否在生成的html中设置自动转义模式
'autoescape' => true,
// 是否必须使用HTML隐式格式化输出
'automatic_html' => true,
// 是否立即输出,必须设为true(默认为true),否则调用->output()不输出
'implicit_flush' => true
],
// 安全配置
'security' => [
// 设置由openssl伪随机生成器生成的字节数
'random_bytes' => 16,
// 设置默认hash,0=7(CRYPT_BLOWFISH_Y),1(CRYPT_STD_DES),2(CRYPT_EXT_DES),3(CRYPT_MD5),4(CRYPT_BLOWFISH),5(CRYPT_BLOWFISH_A),6(CRYPT_BLOWFISH_X),8(CRYPT_SHA256),9(CRYPT_SHA512)
'default_hash' => 7,
'work_factor' => 8
]
]
];
2、修改config/services.php
/**
* @desc 注册数据库(连接)服务
* @author zhaoyang
* @date 2018年5月14日 下午9:01:36
*/
/* $di->setShared('db', function () {
$dbConfig = $this->getConfig()->services->db->toArray();
$mysql = new Mysql($dbConfig);
if ($dbConfig['logged'] ?? false) {
$eventsManager = new EventsManager();
$eventsManager->attach('db', new DbProfilerPlugin());
$mysql->setEventsManager($eventsManager);
}
return $mysql;
}); */
/**
* @desc 注册主(写)数据库连接服务
* @author: ZhaoYang
* @date: 2018年6月19日 下午9:15:21
*/
$di->setShared('dbMaster', function () {
$dbConfig = $this->getConfig()->services->db->toArray();
$masterConfig = $dbConfig['master'];
$i = mt_rand(0, 100) % count($masterConfig);
$mysql = new Mysql($masterConfig[$i]);
if ($dbConfig['logged'] ?? false) {
$eventsManager = new EventsManager();
$eventsManager->attach('db', new DbProfilerPlugin());
$mysql->setEventsManager($eventsManager);
}
return $mysql;
});
/**
* @desc 注册从(读)数据库连接服务
* @author: ZhaoYang
* @date: 2018年6月19日 下午9:15:44
*/
$di->setShared('dbSlave', function () {
$dbConfig = $this->getConfig()->services->db->toArray();
$slaveConfig = $dbConfig['slave'];
$i = mt_rand(0, 100) % count($slaveConfig);
$mysql = new Mysql($slaveConfig[$i]);
if ($dbConfig['logged'] ?? false) {
$eventsManager = new EventsManager();
$eventsManager->attach('db', new DbProfilerPlugin());
$mysql->setEventsManager($eventsManager);
}
return $mysql;
});
完整的config/services.php
<?php
/**
* @desc 注册服务
* @author zhaoyang
* @date 2018年5月3日 下午8:01:34
*/
use Common\Common;
use Common\Validate;
use Library\Extensions\VoltExtension;
use Library\Plugins\DbProfilerPlugin;
use Library\Plugins\DIspatcherPlugin;
use Phalcon\Cache\Frontend\Factory as CacheFrontendFactory;
use Phalcon\Cache\Backend\Factory as CacheBackendFactory;
use Phalcon\Config;
use Phalcon\Crypt;
use Phalcon\Db\Adapter\Pdo\Mysql;
use Phalcon\Db\Profiler;
use Phalcon\DI;
use Phalcon\Di\FactoryDefault;
use Phalcon\Events\Manager as EventsManager;
use Phalcon\Flash\Direct as FlashDirect;
use Phalcon\Flash\Session as FlashSession;
use Phalcon\Http\Response\Cookies;
use Phalcon\Logger\Adapter\File as LoggerAdapterFile;
use Phalcon\Logger\Formatter\Line as LoggerFormatterLine;
use Phalcon\Mvc\Dispatcher;
use Phalcon\Mvc\Router;
use Phalcon\Mvc\Url;
use Phalcon\Mvc\View;
use Phalcon\Mvc\View\Engine\Php as ViewEnginePhp;
use Phalcon\Mvc\View\Engine\Volt as ViewEngineVolt;
use Phalcon\Security;
use Phalcon\Session\Factory as SessionFactory;
use Phalcon\Text;
$di = new FactoryDefault();
/**
* @desc 注册调度器服务
* @author zhaoyang
* @date 2018年5月3日 下午8:38:34
*/
$di->setShared('dispatcher', function () {
$config = $this->getConfig();
$dispatcher = new Dispatcher();
$defaultNamespace = $config->module_default_namespaces ?? DEFAULT_MODULE_NAMESPACE . '\\Controllers';
$dispatcher->setDefaultNamespace($defaultNamespace);
$eventsManager = new EventsManager();
$eventsManager->attach('dispatch', new DIspatcherPlugin());
$dispatcher->setEventsManager($eventsManager);
return $dispatcher;
});
/**
* @desc 注册配置服务
* @author zhaoyang
* @date 2018年5月3日 下午8:38:53
*/
$di->setShared('config', function () use ($config) {
return new Config($config);
});
/**
* @desc 注册路由服务
* @author zhaoyang
* @date 2018年5月3日 下午8:39:06
*/
$di->setShared('router', function () use ($routerRules) {
$router = new Router();
// 自动删除末尾斜线
$router->removeExtraSlashes(true);
foreach ($routerRules as $k => $v) {
$router->add($k, $v);
}
return $router;
});
/**
* @desc 注册视图引擎volt服务
* @author zhaoyang
* @date 2018年5月4日 下午5:28:52
*/
$di->setShared('viewEngineVolt', function (View $view, DI $di) {
// 获取config服务有多种方法,这是其一
$voltConfig = $di->get('config')->services->view_engine_volt->toArray();
$voltConfig = Common::convertArrKeyUnderline($voltConfig);
$viewEngineVolt = new ViewEngineVolt($view, $di);
$voltConfig['compiledPath'] = isset($voltConfig['compiledPath']) ? Common::dirFormat($voltConfig['compiledPath']) : BASE_PATH . 'runtime/' . DEFAULT_MODULE . '/compiled/volt' . DS;
$mkdirRes = Common::mkdir($voltConfig['compiledPath']);
if (!$mkdirRes) {
throw new \Exception('创建目录 ' . $voltConfig['compiledPath'] . ' 失败');
}
$viewEngineVolt->setOptions($voltConfig);
// 获取编译器对象
$compiler = $viewEngineVolt->getCompiler();
// 添加扩展
$compiler->addExtension(new VoltExtension());
return $viewEngineVolt;
});
/**
* @desc 注册视图引擎php服务
* @author zhaoyang
* @date 2018年5月4日 下午5:29:15
*/
$di->setShared('viewEnginePhp', function (View $view, DI $di) {
$viewEnginePhp = new ViewEnginePhp($view, $di);
return $viewEnginePhp;
});
/**
* @desc 注册视图服务
* @author zhaoyang
* @date 2018年5月3日 下午10:52:37
*/
$di->set('view', function () {
// 获取config服务有多种方法,这是其二
$viewConfig = $this->getConfig()->services->view;
$viewDir = $viewConfig->view_path ?? APP_PATH . DEFAULT_MODULE . '/views' . DS;
if (isset($viewConfig->view_suffix)) {
$viewSuffixs = explode(',', $viewConfig->view_suffix);
} else {
$viewSuffixs = [
'volt'
];
}
if (isset($viewConfig->view_service)) {
$viewServices = explode(',', $viewConfig->view_service);
} else {
$viewServices = [
'viewEngineVolt'
];
}
$engines = [ ];
foreach ($viewSuffixs as $k => $v) {
$suffix = '.' . ltrim($v, '.');
$engines[$suffix] = $viewServices[$k] ?? $viewServices[0];
}
$view = new View();
// 设置视图路径
$view->setViewsDir($viewDir);
// 注册视图引擎
$view->registerEngines($engines);
$disableLevelConfig = $viewConfig->disable_level;
// 关闭渲染级别
$disableLevel = [ ];
foreach ($disableLevelConfig as $k => $v) {
if ($v) {
switch ($k) {
case 'level_action_view':
$disableLevel[View::LEVEL_ACTION_VIEW] = true;
break;
case 'level_before_template':
$disableLevel[View::LEVEL_BEFORE_TEMPLATE] = true;
break;
case 'level_layout':
$disableLevel[View::LEVEL_LAYOUT] = true;
break;
case 'level_after_template':
$disableLevel[View::LEVEL_AFTER_TEMPLATE] = true;
break;
case 'level_main_layout':
$disableLevel[View::LEVEL_MAIN_LAYOUT] = true;
break;
}
}
}
$view->disableLevel($disableLevel);
return $view;
});
/**
* @desc 注册验证服务
* @author zhaoyang
* @date 2018年5月11日 下午7:26:30
*/
$di->set('validate', function () {
$validate = new Validate();
return $validate;
});
/**
* @desc 注册性能分析组件
* @author zhaoyang
* @date 2018年5月20日 下午9:34:33
*/
$di->setShared('profiler', function () {
$profiler = new Profiler();
return $profiler;
});
/**
* @desc 注册数据库(连接)服务
* @author zhaoyang
* @date 2018年5月14日 下午9:01:36
*/
/* $di->setShared('db', function () {
$dbConfig = $this->getConfig()->services->db->toArray();
$mysql = new Mysql($dbConfig);
if ($dbConfig['logged'] ?? false) {
$eventsManager = new EventsManager();
$eventsManager->attach('db', new DbProfilerPlugin());
$mysql->setEventsManager($eventsManager);
}
return $mysql;
}); */
/**
* @desc 注册主(写)数据库连接服务
* @author: ZhaoYang
* @date: 2018年6月19日 下午9:15:21
*/
$di->setShared('dbMaster', function () {
$dbConfig = $this->getConfig()->services->db->toArray();
$masterConfig = $dbConfig['master'];
$i = mt_rand(0, 100) % count($masterConfig);
$mysql = new Mysql($masterConfig[$i]);
if ($dbConfig['logged'] ?? false) {
$eventsManager = new EventsManager();
$eventsManager->attach('db', new DbProfilerPlugin());
$mysql->setEventsManager($eventsManager);
}
return $mysql;
});
/**
* @desc 注册从(读)数据库连接服务
* @author: ZhaoYang
* @date: 2018年6月19日 下午9:15:44
*/
$di->setShared('dbSlave', function () {
$dbConfig = $this->getConfig()->services->db->toArray();
$slaveConfig = $dbConfig['slave'];
$i = mt_rand(0, 100) % count($slaveConfig);
$mysql = new Mysql($slaveConfig[$i]);
if ($dbConfig['logged'] ?? false) {
$eventsManager = new EventsManager();
$eventsManager->attach('db', new DbProfilerPlugin());
$mysql->setEventsManager($eventsManager);
}
return $mysql;
});
/**
* @desc 注册日志服务
* @author zhaoyang
* @date 2018年5月19日 下午6:20:36
*/
$di->set('logger', function (string $file = null, array $line = null) {
$config = $this->getConfig()->services->logger;
$linConfig = clone $config->line;
!is_null($line) && $linConfig = $linConfig->merge(new Config($line));
$loggerFormatterLine = new LoggerFormatterLine($linConfig->format, $linConfig->date_format);
$fileConfig = $config->file;
if (empty($file)) {
$file = $fileConfig->info;
} else if (array_key_exists($file, $fileConfig->toArray())) {
$file = $fileConfig->$file;
}
$file = Common::dirFormat($file);
$dir = dirname($file);
$mkdirRes = Common::mkdir($dir);
if (!$mkdirRes) {
throw new \Exception('创建目录 ' . $dir . ' 失败');
}
$loggerAdapterFile = new LoggerAdapterFile($file);
$loggerAdapterFile->setFormatter($loggerFormatterLine);
return $loggerAdapterFile;
});
/**
* @desc 注册session服务
* @author zhaoyang
* @date 2018年5月26日 下午4:48:03
*/
$di->setShared('session', function () {
$sessionConfig = $this->getConfig()->services->session;
$backendConfig = $this->getConfig()->services->cache->backend;
$optionsArr = $sessionConfig->options->toArray();
if (!isset($optionsArr['adapter'])) {
throw new \Exception('session必须设置adapter');
}
if (array_key_exists($optionsArr['adapter'], $backendConfig->toArray())) {
$backendOption = clone $backendConfig->{$optionsArr['adapter']};
$optionsArr = $backendOption->merge(new Config($optionsArr))->toArray();
}
$optionsArr = Common::convertArrKeyUnderline($optionsArr);
if (version_compare(PHALCON_VERSION, '3.2.0', '>')) {
$session = SessionFactory::load($optionsArr);
} else {
$adapterClassName = 'Phalcon\\Session\\Adapter\\' . Text::camelize($optionsArr['adapter']);
$session = new $adapterClassName($optionsArr);
}
$sessionConfig->auto_start && $session->start();
return $session;
});
/**
* @desc 注册加密服务
* @author zhaoyang
* @date 2018年5月28日 下午8:17:46
*/
$di->set('crypt', function (string $key = null, int $padding = null, string $cipher = null) {
$cryptConfig = $this->getConfig()->services->crypt;
$crypt = new Crypt();
if (!empty($cryptConfig->key) || !empty($padding)) {
$crypt->setKey($key ?? $cryptConfig->key);
}
if (!empty($cryptConfig->padding) || !empty($key)) {
$crypt->setPadding($padding ?? $cryptConfig->padding);
}
if (!empty($cryptConfig->cipher) || !empty($cipher)) {
$crypt->setCipher($cipher ?? $cryptConfig->cipher);
}
return $crypt;
});
/**
* @desc 注册cookies服务
* @author zhaoyang
* @date 2018年5月29日 上午9:54:23
*/
$di->set('cookies', function () {
$cookiesConfig = $this->getConfig()->services->cookies;
$cookies = new Cookies();
isset($cookiesConfig->use_encryption) && $cookies->useEncryption((bool) $cookiesConfig->use_encryption);
return $cookies;
});
/**
* @desc 注册缓存
* @author zhaoyang
* @date 2018年5月30日 下午10:30:29
*/
$di->set('cache', function (array $options = []) {
$cacheConfig = $this->getConfig()->services->cache;
$frontendConfig = $cacheConfig->frontend;
if (isset($options['frontend']['adapter'])) {
$frontendOption = new Config($options['frontend']);
if (array_key_exists($options['frontend']['adapter'], $frontendConfig->toArray())) {
$frontendOptionClone = clone $frontendConfig->{$options['frontend']['adapter']};
$frontendOptionClone->merge($frontendOption);
$frontendOption = $frontendOptionClone;
}
} else {
$frontendOption = clone $frontendConfig->data;
$frontendOption->adapter = 'data';
}
$frontendOption = Common::convertArrKeyUnderline($frontendOption->toArray());
if (version_compare(PHALCON_VERSION, '3.2.0', '>')) {
$frontendCache = CacheFrontendFactory::load($frontendOption);
} else {
$frontendClassName = 'Phalcon\\Cache\\Frontend\\' . Text::camelize($frontendOption['adapter']);
$frontendCache = new $frontendClassName($frontendOption);
}
$backendConfig = $cacheConfig->backend;
if (isset($options['backend']['adapter'])) {
$backendOption = new Config($options['backend']);
if (array_key_exists($options['backend']['adapter'], $backendConfig->toArray())) {
$backendOptionClone = clone $backendConfig->{$options['backend']['adapter']};
$backendOptionClone->merge($backendOption);
$backendOption = $backendOptionClone;
}
} else {
$backendOption = clone $backendConfig->file;
$backendOption->adapter = 'file';
}
if ($backendOption->adapter == 'file') {
if (empty($dir = $backendOption->cache_dir)) {
throw new \Exception('缓存目录不能为空');
}
$dir = Common::dirFormat($dir);
$mkdirRes = Common::mkdir($dir);
if (!$mkdirRes) {
throw new \Exception('创建目录 ' . $dir . ' 失败');
}
}
$backendOption = Common::convertArrKeyUnderline($backendOption->toArray());
if (version_compare(PHALCON_VERSION, '3.2.0', '>')) {
$backendOption['frontend'] = $frontendCache;
$backendCache = CacheBackendFactory::load($backendOption);
} else {
$backendClassName = 'Phalcon\\Cache\\Backend\\' . Text::camelize($backendOption['adapter']);
$backendCache = new $backendClassName($frontendCache, $backendOption);
}
return $backendCache;
});
/**
* @desc 注册 modelsMetadata服务
* @author zhaoyang
* @date 2018年6月2日 下午10:39:43
*/
$di->setShared('modelsMetadata', function () {
$modelsMetadataConfig = $this->getConfig()->services->models_metadata;
$backendConfig = $this->getConfig()->services->cache->backend;
$optionsArr = $modelsMetadataConfig->options->toArray();
if (!isset($optionsArr['adapter'])) {
throw new \Exception('modelsMetadata必须设置adapter');
}
if (array_key_exists($optionsArr['adapter'], $backendConfig->toArray())) {
$backendOption = clone $backendConfig->{$optionsArr['adapter']};
$optionsArr = $backendOption->merge(new Config($optionsArr))->toArray();
}
if ($optionsArr['adapter'] == 'files') {
if (empty($optionsArr['meta_data_dir'])) {
throw new \Exception('缓存目录不能为空');
}
$dir = Common::dirFormat($optionsArr['meta_data_dir']);
$mkdirRes = Common::mkdir($dir);
if (!$mkdirRes) {
throw new \Exception('创建目录 ' . $dir . ' 失败');
}
}
$optionsArr = Common::convertArrKeyUnderline($optionsArr);
$modelsMetadataClassName = 'Phalcon\\Mvc\\Model\\MetaData\\' . Text::camelize($optionsArr['adapter']);
$modelsMetadata = new $modelsMetadataClassName($optionsArr);
return $modelsMetadata;
});
/**
* @desc 注册modelsCache服务
* @author zhaoyang
* @date 2018年6月3日 下午6:22:31
*/
$di->set('modelsCache', function (array $options = []) {
$modelsCacheConfig = clone $this->getConfig()->services->models_cache;
!empty($options) && $modelsCacheConfig->merge(new Config($options));
$options = $modelsCacheConfig->toArray();
$modelsCache = $this->get('cache', [
$options
]);
return $modelsCache;
});
/**
* @desc 注册视图缓存
* @author zhaoyang
* @date 2018年6月4日 下午10:14:52
*/
$di->set('viewCache', function (array $options = []) {
$viewCacheConfig = clone $this->getConfig()->services->view_cache;
!empty($options) && $viewCacheConfig->merge(new Config($options));
$options = $viewCacheConfig->toArray();
$viewCache = $this->get('cache', [
$options
]);
return $viewCache;
});
/**
* @desc 注册url服务
* @author zhaoyang
* @date 2018年6月6日 下午8:13:37
*/
$di->setShared('url', function () {
$urlConfig = $this->getConfig()->services->url;
$url = new Url();
$urlConfig->base_uri && $url->setBaseUri($urlConfig->base_uri);
$urlConfig->static_base_uri && $url->setStaticBaseUri($urlConfig->static_base_uri);
$urlConfig->base_path && $url->setBasePath($urlConfig->base_path);
return $url;
});
/**
* @desc 注册flash服务
* @author zhaoyang
* @date 2018年6月9日 下午8:22:46
*/
$di->set('flash', function () {
$flashConfig = $this->getConfig()->services->flash;
$flashDirect = new FlashDirect($flashConfig->css_classes->toArray());
$flashDirect->setAutoescape($flashConfig->autoescape);
$flashDirect->setAutomaticHtml($flashConfig->automatic_html);
$flashDirect->setImplicitFlush($flashConfig->implicit_flush);
return $flashDirect;
});
/**
* @desc 注册flashSession服务
* @author zhaoyang
* @date 2018年6月9日 下午8:23:45
*/
$di->set('flashSession', function () {
$flashSessionConfig = $this->getConfig()->services->flash_session;
$flashSession = new FlashSession($flashSessionConfig->css_classes->toArray());
$flashSession->setAutoescape($flashSessionConfig->autoescape);
$flashSession->setAutomaticHtml($flashSessionConfig->automatic_html);
$flashSession->setImplicitFlush($flashSessionConfig->implicit_flush);
return $flashSession;
});
/**
* @desc 注册安全服务
* @author zhaoyang
* @date 2018年6月7日 下午9:19:07
*/
$di->set('security', function () {
$securityConfig = $this->getConfig()->services->security;
$security = new Security();
$securityConfig->random_bytes && $security->setRandomBytes($securityConfig->random_bytes);
$securityConfig->default_hash && $security->setDefaultHash($securityConfig->default_hash);
$securityConfig->work_factor && $security->setWorkFactor($securityConfig->work_factor);
return $security;
});
3、在common下创建BaseModel.php模型基类
<?php
/**
* @desc 基础模型
* @author: ZhaoYang
* @date: 2018年6月19日 下午9:31:51
*/
namespace Common;
use Phalcon\Mvc\Model;
class BaseModel extends Model {
/**
* @desc 初始化
* @author: ZhaoYang
* @date: 2018年6月19日 下午9:32:08
*/
public function initialize() {
$dbConfig = $this->di->getConfig()->services->db;
$this->useDynamicUpdate($dbConfig->use_dynamic_update);
$this->setup($dbConfig->orm_options->toArray());
$this->setReadConnectionService('dbSlave');
$this->setWriteConnectionService('dbMaster');
}
}
4、打开app/home/models/Robots.php
修改为
<?php
namespace App\Home\Models;
// use Phalcon\Mvc\Model;
// use Common\Validate;
use Common\BaseModel;
class Robots extends BaseModel {
public function initialize() {
parent::initialize();
$this->setSource('ph_robots');
}
/**
* @desc 插入之前验证
* @author zhaoyang
* @date 2018年5月16日 下午10:57:48
*/
public function beforeValidationOnCreate() {
$rules = [
//表示name插入时必须验证
['name', 'regex', '姓名必须为6-10位数字字母下划线', '/^[a-zA-Z\d_]{6,10}$/', 1],
// 或者这么写
// ['name', 'alnum', '姓名必须为字母数字', '', 1],
// ['name', 'stringlength', '姓名长度为6-10位', [6,10], 1],
// ['name', 'uniqueness', '姓名已存在', '', 1],
// 表示插入时必须验证
['type', 'inclusionin', '类型只能为1,2,3', [1,2,3], 1],
// 也可以这么写
// ['type', 'callback', '类型只能为1,2,3', function ($data) {
// $type = $data->type ?? null;
// if (in_array($type, [1, 2, 3])){
// return true;
// }else{
// return false;
// }
// }, 1],
// 表示插入时必须验证
['weight', 'digit', '重量只能为数字', '', 1],
['weight', 'between', '重量只能在1-200之间', [1, 200], 1],
// 或者这么写
// ['weight', 'regex', '重量只能在1-200之间的整数', '/^(1\d?\d?)|200$/', 1],
];
$validate = $this->getDI()->getValidate()->addRules($rules);
// $validate = new Validate();
// $validate = $validate->addRules($rules);
return $this->validate($validate);
}
/**
* @desc 更新之前验证
* @author zhaoyang
* @date 2018年5月16日 下午10:57:57
*/
public function beforeValidationOnUpdate() {
$rules = [
//表示name更新时必须验证
['name', 'regex', '姓名必须为6-10位数字字母下划线', '/^[a-zA-Z\d_]{6,10}$/', 1],
['name', 'uniqueness', '姓名已存在', '', 1],
// 表示更新时存在即验证
// ['type', 'inclusionin', '类型只能为1,2,3', [1,2,3]],
//或者
['type', 'callback', '类型只能为1,2,3', function ($data) {
$type = $data->type ?? null;
return $data->checkType($type);
}, 1],
// 表示更新时存在即验证
['weight', 'digit', '重量只能为数字'],
['weight', 'between', '重量只能在1-200之间', [1, 200]],
];
$validate = $this->getDI()->getValidate()->addRules($rules);
return $this->validate($validate);
}
public function checkType($type){
if (in_array($type, [1, 2, 3])){
return true;
}else{
return false;
}
}
}
5、home下的RobotsController.php控制器无需更改
<?php
namespace App\Home\Controllers;
use Common\BaseController;
use App\Home\Models\Robots;
class RobotsController extends BaseController {
public function initialize() {
echo '<pre>';
$this->view->disable();
}
public function indexAction() {
$robotsList = Robots::find();
foreach ($robotsList as $robot){
echo $robot->id,' ',$robot->name,' ',$robot->type,' ',$robot->weight,'<br/>';
}
}
public function addAction() {
$data = $this->get();
$robots = new Robots();
$res = $robots->create($data); // or save($data)
var_dump($res, $robots->id ?? '插入失败', $robots->getMessages());exit;
}
public function infoAction() {
$id = $this->get('id', 'int');
$this->config->services->db->logged = true;
$robot = Robots::findFirst($id);
echo $robot->id,' ',$robot->name,' ',$robot->type,' ',$robot->weight;exit;
}
public function editAction() {
$data = $this->get();
$robot = Robots::findFirst($data['id']);
$res = $robot->update($data); // or save($data)
var_dump($res, $res ? '更新成功' : '更新失败', $robot->getMessages());exit;
}
public function deleteAction() {
$id = $this->get('id', 'int');
$robot = Robots::findFirst($id);
$res = $robot->delete();
var_dump($res, $res ? '删除成功' : '删除失败', $robot->getMessages());exit;
}
}
为了测试效果,我们把执行dbMaster和dbSlave语句分别存放在不同的文件中,来区别执行效果。
4、访问/robots/index
打开runtime目录可以看到mysql目录下多出了
访问/robots/add/name/robot_four/type/2/weight/90
在runtime/mysql下会看到
到这里读写分离配置测试完成