View previous topic :: View next topic |
Author |
Message |
Fortael Smarty Rookie
Joined: 12 Nov 2014 Posts: 8
|
Posted: Wed Nov 12, 2014 6:17 am Post subject: Autoload |
|
|
I cant use my autoloader for helpers, in index.php by spl_autoload_register(); Because autoloader try load smarty.
Code: | public function index() {
load::smarty();
$this->smarty->display(...);
} |
"load" is helper. Where
Code: |
class load extend CTRL {
public function smarty() {
require_once '/app/smarty/Smarty.php';
$this->smarty = new Smarty()
}
}
|
Result
Code: |
Warning: require(app/helper/Smarty_Internal_TemplateCompilerBase.php) [function.require]: failed to open stream: No such file or directory in Z:\home\domain.com\www\index.php on line 75
Fatal error: require() [function.require]: Failed opening required 'app/helper/Smarty_Internal_TemplateCompilerBase.php' (include_path='.;C:\php\pear') in Z:\home\domain.com\www\index.php on line 75
|
|
|
Back to top |
|
U.Tews Administrator
Joined: 22 Nov 2006 Posts: 5068 Location: Hamburg / Germany
|
Posted: Wed Nov 12, 2014 4:06 pm Post subject: |
|
|
Smarty does install it's own autoloader. But to get this done you have to load Smarty.php with include_once . |
|
Back to top |
|
Fortael Smarty Rookie
Joined: 12 Nov 2014 Posts: 8
|
Posted: Thu Nov 13, 2014 11:25 am Post subject: |
|
|
U.Tews wrote: | Smarty does install it's own autoloader. But to get this done you have to load Smarty.php with include_once . |
Smarty itself should be load this class before using. You can fix it?
Controller.php
Code: |
<?php
spl_autoload_register(array('CTRL', 'loadHelper'));
class CTRL {
public static function loadHelper($className) {
require_once APP . 'helper/' . $className . '.php';
}
}
|
Next
load.php
Code: |
class load {
public function lib() {
$folder = APP. 'lib/';
$list = func_get_args();
try {
foreach ($list as $value) {
$class = $value;
if (preg_match('[/]', $value)) {
$explode = explode('/',$value);
$class = array_pop($explode);
}
if (file_exists($folder.$value.'.php')) {
require_once $folder.$value.'.php';
if (class_exists($class)) {
$this->$class = new $class();
} else {
throw new Exception('This class is already taken '.$class);
}
} else {
throw new Exception('Undefined class '.$value);
}
}
} catch (Exception $ex) {
$ex->getMessage();
}
}
}
|
I use require_once.
view.php has load Smarty.php. And set options for smarty
view.php
Code: |
<?php
require_once APP.'lib/smarty/Smarty.class.php';
define('VIEW', APP.'view/');
class view extends Smarty {
public $title;
private $header_tpl = 'frame/header.tpl';
private $navigation_tpl = 'frame/navigation.tpl';
private $footer_tpl = 'frame/footer.tpl';
public function __construct() {
parent::__construct();
$this->template_dir = APP.'view/';
$this->compile_dir = CACHE.'compiled/';
$this->cache_dir = CACHE.'smarty/';
}
}
|
Result:
Code: | Warning: include_once(app/helper/Smarty_Internal_Templatelexer.php) [function.include-once]: failed to open stream: No such file or directory in Z:\home\sd.com\www\system\core\Controller.php on line 8
Warning: include_once() [function.include]: Failed opening 'app/helper/Smarty_Internal_Templatelexer.php' for inclusion (include_path='.;C:\php\pear') in Z:\home\sd.com\www\system\core\Controller.php on line 8
Warning: include_once(app/helper/Smarty_Internal_Templateparser.php) [function.include-once]: failed to open stream: No such file or directory in Z:\home\sd.com\www\system\core\Controller.php on line 8
Warning: include_once() [function.include]: Failed opening 'app/helper/Smarty_Internal_Templateparser.php' for inclusion (include_path='.;C:\php\pear') in Z:\home\sd.com\www\system\core\Controller.php on line 8
Warning: include_once(app/helper/Smarty_Internal_Write_File.php) [function.include-once]: failed to open stream: No such file or directory in Z:\home\sd.com\www\system\core\Controller.php on line 8
Warning: include_once() [function.include]: Failed opening 'app/helper/Smarty_Internal_Write_File.php' for inclusion (include_path='.;C:\php\pear') in Z:\home\sd.com\www\system\core\Controller.php on line 8 |
sd.com - denwer domain (local webserver)
I can set error_reporting(0), but this does not solve the problem |
|
Back to top |
|
U.Tews Administrator
Joined: 22 Nov 2006 Posts: 5068 Location: Hamburg / Germany
|
Posted: Thu Nov 13, 2014 6:29 pm Post subject: |
|
|
Autoloaders must check if it can handle the request. If not just return to give other autoloaders like Smarty's a chance.
Controller.php
Code: | ?php
spl_autoload_register(array('CTRL', 'loadHelper'));
class CTRL {
public static function loadHelper($className) {
if (is_file($file = APP . 'helper/' . $className . '.php')) {
require $file;
}
}
} |
Or sort out all class names starting with Smarty already befor is_file call for speed
Code: |
public static function loadHelper($className) {
if (0 !== strpos($class, 'Smarty') && is_file($file = APP . 'helper/' . $className . '.php')) {
require $file;
}
}
|
Use require whenever possible. require_once is slow and should only be used if your application could get there twice. |
|
Back to top |
|
Fortael Smarty Rookie
Joined: 12 Nov 2014 Posts: 8
|
Posted: Fri Nov 14, 2014 12:20 pm Post subject: |
|
|
But the message of the absence of the file still remains. Why smarty used class which not loaded? Why my autoloader tried load him class..If smarty will load all the necessary classes to it, it will not be |
|
Back to top |
|
U.Tews Administrator
Joined: 22 Nov 2006 Posts: 5068 Location: Hamburg / Germany
|
Posted: Fri Nov 14, 2014 7:56 pm Post subject: |
|
|
If a class is requested which is not loaded the system will send a load request to all registered autoloader in sequence until any of them is able to load the file.
Each autoloader must test if it can load the class file, if not just return.
As you can see in the error message the error occurs at Controller.php on line 8.
It tries to include Smarty files which are not present in that filepath.
So Controller.php must check with is_file() if it can load the file or not. |
|
Back to top |
|
AnrDaemon Administrator
Joined: 03 Dec 2012 Posts: 1785
|
Posted: Fri Nov 21, 2014 1:25 am Post subject: |
|
|
Rather, you must not use "require" in autoloader. Ever.
include_once plus check the result of include. |
|
Back to top |
|
U.Tews Administrator
Joined: 22 Nov 2006 Posts: 5068 Location: Hamburg / Germany
|
Posted: Sun Nov 23, 2014 12:53 am Post subject: |
|
|
Don't use require_once or include_once in autoloaders. Include or require has better performance.
Also the autoloader must check if the file exists with is_file( ) or file_exits().
Using include and checking the results is bad practice as as it creates warnings in case of failure. |
|
Back to top |
|
AnrDaemon Administrator
Joined: 03 Dec 2012 Posts: 1785
|
Posted: Sun Nov 23, 2014 7:15 pm Post subject: |
|
|
Right you are, I wrote "once" without applying brain to fingers.
Of course, if class definition is already loaded, it won't be tried again, so using include is technically equivalent to include_once. |
|
Back to top |
|
|