
2008-7-2 19:06
zoujinhe
每次都load ini,很耗時,很不爽,怎麼讓它只load一次ini?
每個request都會load一次ini,硬盤io很慢啊,再說new那些Object也花很多時間的,用zend profiler看,60%的時間花在ini上。
[php]
<?php
error_reporting(E_ALL|E_STRICT);
date_default_timezone_set('Asia/Shanghai');
$ds = DIRECTORY_SEPARATOR;//目录分隔符号
$ps = PATH_SEPARATOR;//路径分隔符号
define('ABS_ROOT_PATH', realpath(dirname(__FILE__)));
define('REL_ROOT_PATH', substr($_SERVER['PHP_SELF'], 0 , strpos($_SERVER['PHP_SELF'],'/index.php')));
set_include_path('.'.PATH_SEPARATOR.'./library'.PATH_SEPARATOR.'./application/models/'.PATH_SEPARATOR.get_include_path());
require_once 'Zend/Loader.php';
//自动加载类
Zend_Loader::registerAutoload();
//数据库配置
$dbParams = new Zend_Config_Ini('./config/config.ini','SysDB');
$db = Zend_Db::factory($dbParams->adapter,$dbParams->toArray());
$db->query("set names {$dbParams->charset};");
Zend_Db_Table::setDefaultAdapter($db);
Zend_Registry::set('sysdb',$db);
//SMARTY配置
$smartyParams = new Zend_Config_Ini('./config/config.ini', 'SysTpl');
$smarty = new Custom_View_Smarty($smartyParams->toArray());
Zend_Registry::set('systpl',$smarty);
//全局定义
$sysinfoParams = new Zend_Config_Ini('./config/config.ini','SysGlobalInfo');
Zend_Registry::set('sysinfo',$sysinfoParams->toArray());
//初始控制器
$router = new Zend_Controller_Router_Rewrite();
$frontController = Zend_Controller_Front::getInstance();
$frontController->setRouter($router);
$frontController->setControllerDirectory(array(
'default' => './application/controllers',
));
$frontController->throwExceptions(true);
$frontController->setParam('noViewRenderer',true);
$frontController->setBaseUrl(REL_ROOT_PATH);
try{
$frontController->dispatch();
}catch(Zend_Controller_Dispatcher_Exception $e){
echo nl2br($e->__toString());
}
unset($db);
unset($smarty);
?>
[/php]
2008-7-3 02:36
fidy
//配置文件:
$patams = new Zend_Config_Ini('./config/config.ini');
//数据库配置
$dbParams = $patams->SysDB;
//SMARTY配置
$smartyParams = $patams->SysTpl;
//全局定义
$sysinfoParams = $patams->SysGlobalInfo;
2008-7-3 17:15
zoujinhe
楼上,你这个还不是每次都load了ini!!!
2008-7-4 03:22
fidy
第一,我比你少load了两次ini
第二,我比你少new了两个对象
第三,除非你的配置参数不在硬盘上,而在内存里(写入memcache,严格地说也不能保证你只load一次ini),否则就要load文件和初始化对象
第四,你打那么多叹号啥意思,我欠过你钱还是咋的???
2008-7-4 10:17
zoujinhe
第四,你打那么多叹号啥意思,我欠过你钱还是咋的???
>>>>謝謝您的回答,不過老實說,你的回答並無任何參考價值!
2008-7-4 18:46
fidy
在load ini的问题上,我的效率比你的快三倍,对你还没什么参考价值,我很遗憾,或许你对自己load三次ini有更好的解释,愿闻其详
即便使用memcache,加载相关类文件造成的io开销也不比loadini低,所以没有更好的方案
如果自己不动脑子,任何回答都不会有参考价值
2008-7-5 03:43
geel
第一点:
$ps = PATH_SEPARATOR;//路径分隔符号
set_include_path('.'.PATH_SEPARATOR.'./library'.PATH_SEPARATOR.'./application/models/'.PATH_SEPARATOR.get_include_path());
貌似你把 PATH_SEPARATOR 赋值给了$ps 是为了方便用,但是接下来又用了比较复杂的PATH_SEPARATOR
$ds $ps都没有用到,这么做是为了什么?
第二点:
autoload不怕影响性能吗
第三点:
define('REL_ROOT_PATH', substr($_SERVER['PHP_SELF'], 0 , strpos($_SERVER['PHP_SELF'],'/index.php')));
一个dirname就可以搞定的,写这么麻烦干嘛呢
第四点:
require_once 'Zend/Loader.php';
你include Zend/Controller/Front.php之后,Loader就被加载了,改成require_once 'Zend/Controller/Front.php',少写一句话不好吗
第五点:
你同一个配置文件里的东西,为什么要分3次读文件并且让zend::config来解析三次呢,一次不好吗
第六点:
给zend_register里set了3个配置段,建立了3个引用,要是那么追求性能,为什么不set一个呢,为了以后书写方便吗
第七点:
$router = new Zend_Controller_Router_Rewrite();
$frontController = Zend_Controller_Front::getInstance();
$frontController->setRouter($router);
你没对router做任何特殊处理,为什么要手工new一下呢,frontcontroller会自动实例化rewrite的呀
第八点:
$dbParams = new Zend_Config_Ini('./config/config.ini','SysDB');
$db = Zend_Db::factory($dbParams->adapter,$dbParams->toArray());
$db->query("set names {$dbParams->charset};");
Zend_Db_Table::setDefaultAdapter($db);
你所有的action都需要db吗,如果那么在意性能,为什么不需要的地方才初始化呢
综上所述:你只看到了profiler的数据,却没分析怎么优化,对细节也没有把握。你的题目是怎么只load一次,人家也告诉你怎么load一次了,你又说不对,没办法了。
第一次上phpeye,刚用zf,忍不住多说两句,多包涵
[[i] 本帖最后由 geel 于 2008-7-5 03:58 编辑 [/i]]
2008-7-8 10:17
月黑风高
除非是helloworld,我不相信代码60%时间会在load ini上.
2008-7-9 15:34
zoujinhe
geel:
Sorry,這段代碼是從一個教學貼抄過來的,沒有修改!
另外:根據java,asp,aspx的經驗,都有application級別的變量(php沒有),並且有static(真正全局共用),所以我可以判斷ini是否加載過了,db連接是否有初始化過了,例:
if (!app['loaded']){
// loadini
// init db
}
php如何實現上面的做法?
2008-7-11 12:59
jasonqi
[quote]原帖由 [i]zoujinhe[/i] 于 2008-7-9 15:34 发表 [url=http://www.phpeye.com/bbs/redirect.php?goto=findpost&pid=2218&ptid=612][img]http://www.phpeye.com/bbs/images/common/back.gif[/img][/url]
geel:
Sorry,這段代碼是從一個教學貼抄過來的,沒有修改!
另外:根據java,asp,aspx的經驗,都有application級別的變量(php沒有),並且有static(真正全局共用),所以我可以判斷ini是否加載過了,db連接是否有初始化過了,例:
if (! ... [/quote]
[php]public function getDb()
{
if (null === $this->_services['db']) {
$config = $this->config->database;
$this->_services['db'] = Zend_Db::factory($config->type, $config);
}
return $this->_services['db'];
}
[/php]
2008-7-11 16:06
geel
[quote]原帖由 [i]zoujinhe[/i] 于 2008-7-9 15:34 发表 [url=http://www.phpeye.com/bbs/redirect.php?goto=findpost&pid=2218&ptid=612][img]http://www.phpeye.com/bbs/images/common/back.gif[/img][/url]
另外:根據java,asp,aspx的經驗,都有application級別的變量(php沒有),並且有static(真正全局共用),所以我可以判斷ini是否加載過了,db連接是否有初始化過了,例:
if (! ... [/quote]
php运行时没有一个全局容器,所以应用程序级别的东西都没有,如果用apc之类的东西store一个对象,又涉及到能不能很好的序列化的问题。所以有些对象比如db,做到请求级别单例就行了。至于config,存到apc或memcached,但是如果ini文件不大,放memcached的话还不如直接读,tcp和unserialize的开销也挺大
2008-7-12 12:35
zoujinhe
to jasonqi:
對,就是要這種效果。
請問從哪個類繼承才有_services這個屬性?
另外,如果是在非class中,能這樣做嗎?
[[i] 本帖最后由 zoujinhe 于 2008-7-12 12:37 编辑 [/i]]
2008-7-13 15:16
jasonqi
[quote]原帖由 [i]zoujinhe[/i] 于 2008-7-12 12:35 发表 [url=http://www.phpeye.com/bbs/redirect.php?goto=findpost&pid=2234&ptid=612][img]http://www.phpeye.com/bbs/images/common/back.gif[/img][/url]
to jasonqi:
對,就是要這種效果。
請問從哪個類繼承才有_services這個屬性?
另外,如果是在非class中,能這樣做嗎? [/quote]
在ZF中,这种写法很多,例如初始化singleton模式的类。
我只是贴了一个代码片段,所以信息不全,_services就是在这个类里定义的,打个比方,我把bootstrap文件写到一个类里,假设为:
class My_Application {}
在里面定义了一些变量和方法,如 _services, run() {},getDB{}, getAcl(){}, getAuth(){}等等。
这样,在index.php里这样写就可以了:
[php]<?php
require_once '../library/My/Applicationc.php';
My_Application::getInstance()->run();[/php]
这样比把所有初始化的内容都写到index.php里有一些好处,例如并不是所有的控制器都需要DB操作,这样在run(){}里不需要调用getDB(),而在需要DB操错的控制器里的构造器里加上
[php]My_Application::getDB();[/php]
就够了,对于getAcl(),getAuth()等都是同样的道理。
对于执行效率,我觉得需要花时间去调试和修改,对具体的环境要进行针对性的处理才行。
2008-7-13 15:17
jasonqi
[quote]原帖由 [i]zoujinhe[/i] 于 2008-7-12 12:35 发表 [url=http://www.phpeye.com/bbs/redirect.php?goto=findpost&pid=2234&ptid=612][img]http://www.phpeye.com/bbs/images/common/back.gif[/img][/url]
另外,如果是在非class中,能這樣做嗎? [/quote]
看具体情况来定吧
2008-7-14 14:11
zoujinhe
了解,也就是說還是只能做到每請求一次,不能做到全局一次。:(
2008-7-14 14:11
zoujinhe
雙太陽都這樣講了,估計是比較驗實現我的要求了。
2008-7-14 14:28
sentrychen
[quote]原帖由 [i]jasonqi[/i] 于 2008-7-13 15:16 发表 [url=http://www.phpeye.com/bbs/redirect.php?goto=findpost&pid=2243&ptid=612][img]http://www.phpeye.com/bbs/images/common/back.gif[/img][/url]
在ZF中,这种写法很多,例如初始化singleton模式的类。
我只是贴了一个代码片段,所以信息不全,_services就是在这个类里定义的,打个比方,我把bootstrap文件写到一个类里,假设为:
class My_Application {}
在里面定义了一 ... [/quote]
是不是这样子?
index.php
[php]
<?php
ini_set('display_startup_errors', 1);
ini_set('display_errors', 1);
include '../lib/Itc/App.php';
Itc_App::getInstance()->run();
[/php]
App.php
[php]
<?php
if (!defined('ROOT_DIR')) {
define('ROOT_DIR', dirname(dirname(dirname(__FILE__))));
}
//bootstrap class
class Itc_App
{
protected static $_instance = null;
protected $_services = Array();
protected $_disables = Array();
protected function __construct ()
{
set_include_path('.'
. PATH_SEPARATOR . ROOT_DIR . '/lib/'
. PATH_SEPARATOR . ROOT_DIR . '/app/default/models/'
. PATH_SEPARATOR . get_include_path()
);
require_once 'Zend/Loader.php';
Zend_Loader::registerAutoload();
$config = new Zend_Config_Ini(ROOT_DIR . '/etc/config.ini', 'general');
Zend_Registry::set('config', $config);
$this->_services['config'] = $config;
}
public static function getInstance()
{
if (null === self::$_instance) {
self::$_instance = new self();
}
return self::$_instance;
}
public function __get($name)
{
if (!array_key_exists($name, $this->_services)) {
return false;
}
return $this->_services[$name];
}
public function initSession()
{
Zend_Session::setOptions($this->config->session->toArray());
return $this;
}
public function initTimezone()
{
$timezone = $this->config->sys->timezone;
date_default_timezone_set($this->config->sys->timezone);
$this->_services['timezone'] = $timezone;
return $this;
}
public function initTranslate()
{
$translate = Itc_Translate::startTranslate($this->config->lang->toArray());
Zend_Registry::set('Zend_Translate', $translate);
$this->_services['translate'] = $translate;
return $this;
}
public function initCache()
{
$cache = Zend_Cache::factory('Core', 'File',
$this->config->cache->frontend_options->toArray(),
$this->config->cache->backend_options->toArray());
$cache->setOption('caching', ! $this->config->sys->debugging);
$this->_services['cache'] = $cache;
return $this;
}
public function initDb()
{
$db = Zend_Db::factory($this->config->db);
$db->query("set names {$this->config->sys->charset};");
Zend_Registry::set('db', $db);
Itc_Db_Table::setDefaultAdapter($db);
if ($this->cache){
Itc_Db_Table::setDefaultMetadataCache($this->cache);
}
$this->_services['db'] = $db;
return $this;
}
public function initSmarty()
{
$smarty = new Itc_View_Smarty($this->config->smarty->toArray());
$viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer');
$viewRenderer->setView($smarty)->setViewSuffix($this->config->smarty->suffix);
$this->_services['smarty'] = $smarty;
return $this;
}
public function initLayout()
{
$inflector = new Zend_Filter_Inflector(':script.:suffix');
$inflector->addRules(array(':script' => array('Word_CamelCaseToDash', 'StringToLower'),
'suffix' => $this->config->layout->suffix));
$options = array();
$options['layoutPath'] = $this->config->layout->layout_path;
$options['layout'] = $this->config->layout->layout_path;
$options['contentKey'] = $this->config->layout->contentKey;
$options['inflector'] = $inflector;
if ($this->smarty){
$options['view'] = $this->smarty;
}
Zend_Layout::startMvc($options);
return $this;
}
public function disable($disables = null)
{
$disables = (array) $disables;
foreach ($disables as $disable){
$this->_disables[$disable] = true;
}
return $this;
}
public function isDisabled($name)
{
return isset($this->_disables[$name]);
}
public function run()
{
if (!$this->isDisabled('session')){
$this->initSession();
}
if (!$this->isDisabled('timezone')){
$this->initTimezone();
}
if (!$this->isDisabled('translate')){
$this->initTranslate();
}
if (!$this->isDisabled('cache')){
$this->initCache();
}
if (!$this->isDisabled('db')){
$this->initDb();
}
if (!$this->isDisabled('smarty')){
$this->initSmarty();
}
if (!$this->isDisabled('layout')){
$this->initLayout();
}
if (!$this->isDisabled('dispatch')){
$frontController = Zend_Controller_Front::getInstance();
$frontController->setControllerDirectory(array('default' => ROOT_DIR . '/app/default/controllers'));
if ($this->isDisabled('viewRenderer')){
$frontController->setParam('noViewRendere',true);
}
if ($this->isDisabled('errorHandler')){
$frontController->setParam('noErrorHandler',true);
}
if ($this->isDisabled('throwExceptions'))
{
$frontController->dispatch();
}
else
{
$frontController->throwExceptions(true);
try{
$frontController->dispatch();
}catch (Zend_Controller_Exception $e) {
include ROOT_DIR . '/pub/errors/404.phtml';
} catch (Exception $e) {
include ROOT_DIR . '/pub/errors/500.phtml';
}
}
}
}
}
[/php]
[[i] 本帖最后由 sentrychen 于 2008-7-14 15:00 编辑 [/i]]
2008-7-14 14:38
sentrychen
经过测试load ini所占的时间非常小。反而是初始化smarty和zend_layout的时候就很慢,差不多要100-200毫秒。这对于使用ajax时候很不方便,因为ajax不需要这两个对象。jasonqi可以有好办法?重定向规则?
2008-7-15 00:27
jasonqi
[quote]原帖由 [i]zoujinhe[/i] 于 2008-7-14 14:11 发表 [url=http://www.phpeye.com/bbs/redirect.php?goto=findpost&pid=2252&ptid=612][img]http://www.phpeye.com/bbs/images/common/back.gif[/img][/url]
雙太陽都這樣講了,估計是比較驗實現我的要求了。 [/quote]
同学,双太阳不代表技术水平,我的技术水平未必比你高,只是列出我自己对此问题的想法而已,未必是正确或最好的
技术无止境,多看多问,共同提高。-:)
2008-7-15 00:33
jasonqi
[quote]原帖由 [i]sentrychen[/i] 于 2008-7-14 14:38 发表 [url=http://www.phpeye.com/bbs/redirect.php?goto=findpost&pid=2254&ptid=612][img]http://www.phpeye.com/bbs/images/common/back.gif[/img][/url]
经过测试load ini所占的时间非常小。反而是初始化smarty和zend_layout的时候就很慢,差不多要100-200毫秒。这对于使用ajax时候很不方便,因为ajax不需要这两个对象。jasonqi可以有好办法?重定向规则? ... [/quote]
我的代码大致和你的相同,主要的区别是我没有用__get()和Smarty
1)因为要get的东东不多,我就重复写了,想象中节约点时间
2)以前用smarty,现在觉得Zend_View 结合Zend_layout,Zend_Cache挺好
页:
[1]
2
Powered by Discuz! Archiver 5.5.0
© 2001-2006 Comsenz Inc.