Smarty Forum Index Smarty
WARNING: All discussion is moving to https://reddit.com/r/smarty, please go there! This forum will be closing soon.

Autoload

 
This forum is locked: you cannot post, reply to, or edit topics.   This topic is locked: you cannot edit posts or make replies.    Smarty Forum Index -> Bugs
View previous topic :: View next topic  
Author Message
Fortael
Smarty Rookie


Joined: 12 Nov 2014
Posts: 8

PostPosted: Wed Nov 12, 2014 6:17 am    Post subject: Autoload Reply with quote

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
View user's profile Send private message
U.Tews
Administrator


Joined: 22 Nov 2006
Posts: 5068
Location: Hamburg / Germany

PostPosted: Wed Nov 12, 2014 4:06 pm    Post subject: Reply with quote

Smarty does install it's own autoloader. But to get this done you have to load Smarty.php with include_once .
Back to top
View user's profile Send private message
Fortael
Smarty Rookie


Joined: 12 Nov 2014
Posts: 8

PostPosted: Thu Nov 13, 2014 11:25 am    Post subject: Reply with quote

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
Code:
load::lib('view');

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
View user's profile Send private message
U.Tews
Administrator


Joined: 22 Nov 2006
Posts: 5068
Location: Hamburg / Germany

PostPosted: Thu Nov 13, 2014 6:29 pm    Post subject: Reply with quote

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
View user's profile Send private message
Fortael
Smarty Rookie


Joined: 12 Nov 2014
Posts: 8

PostPosted: Fri Nov 14, 2014 12:20 pm    Post subject: Reply with quote

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
View user's profile Send private message
U.Tews
Administrator


Joined: 22 Nov 2006
Posts: 5068
Location: Hamburg / Germany

PostPosted: Fri Nov 14, 2014 7:56 pm    Post subject: Reply with quote

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
View user's profile Send private message
AnrDaemon
Administrator


Joined: 03 Dec 2012
Posts: 1785

PostPosted: Fri Nov 21, 2014 1:25 am    Post subject: Reply with quote

Rather, you must not use "require" in autoloader. Ever.
include_once plus check the result of include.
Back to top
View user's profile Send private message
U.Tews
Administrator


Joined: 22 Nov 2006
Posts: 5068
Location: Hamburg / Germany

PostPosted: Sun Nov 23, 2014 12:53 am    Post subject: Reply with quote

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
View user's profile Send private message
AnrDaemon
Administrator


Joined: 03 Dec 2012
Posts: 1785

PostPosted: Sun Nov 23, 2014 7:15 pm    Post subject: Reply with quote

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
View user's profile Send private message
Display posts from previous:   
This forum is locked: you cannot post, reply to, or edit topics.   This topic is locked: you cannot edit posts or make replies.    Smarty Forum Index -> Bugs All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group
Protected by Anti-Spam ACP