Love Fuel?    Donate

FuelPHP Forums

Ask your question about FuelPHP in the appropriate forum, or help others by answering their questions.
Namespace using class not found
  • So I have defined in my config.php:
          'controller_prefix' => 'Controller\\',
    Path: \fuel\controller\rest\awesome\authentication.php

    which has namespace:
    namespace Controller\Rest\awesome
    But within authentication.php when I am trying to use other class of other namespace:

    Path: \fuel\controller\rest\exceptions\tokenexpiredexception.php
    <?php

    namespace Controller\Rest\Common\Exceptions;
    class TokenExpiredException extends \Exception
    {
    }
    <?php
    namespace Controller\Rest\awesome;

    use Controller\Rest\Common\Exception;

    class Authentication extends \Controller\Rest\Common\Base
    {    

        public function authentication()
        {
    	throw new \TokenExpiredException("Token expired!");
        }
    }  
    Its gives me Class 'TokenExpiredException' not found
    The only way I can do is the following?
    use Controller\Rest\Common\Exceptions as Exceptions;
    then call Exceptions\TokenExpiredException("Token expired!");
    I just want to be like C# or Java, define using the namespace then I can call the classes within the namespace
  • If you tell your code to use Controller\Rest\Common\Exception; it will use the namespace. If, however, you want to use the TokenExpiredException class from that namespace (and just that) then you would have to

    use Controller\Rest\Common\Exception\TokenExpiredException;

    Then, \throw new \TokenExpiredCollection('Token Expired') will work just fine.
  • Path: \fuel\controller\rest\awesome\authentication.php

    Is incorrect too, all classes have to be in a "classes" folder, either in app, in a module, or a package. Otherwise the autoloader can't find them.

    So this should be:

    \fuel\app\classes\controller\rest\awesome\authentication.php

    But since your controller loads I assume that was a typo?
  • @philipptempel 
    I think I understand on what you said about:

    use Controller\Rest\Common\Exception\TokenExpiredException;

     \throw new \TokenExpiredCollection('Token Expired') 

    However, I don't what really understand what use Controller\Rest\Common\Exception; does .
    Its uses the namespace, but doesn't let me call any of the classes from inside like C#?
    So what does it do?

    Because I want to avoid define a lot of 'use namespace'.
    Recently I just figured out I could call the classes inside by doing Exception\TokenExpiredException, is that the correct way of doing it?

    @Harro Yes, that was my typo :) they were all inside classes folder.
  • It's where you defined the class.

    FuelPHP uses a cascading file system, in which the namespace and classname reflect the path and filename of the file that stores the class.

    So if you have a file called /fuel/classes/controller/rest/exceptions/tokenexpiredexception.php, it defines the classes Tokenexpiredexception in the namaspace \controller\rest\exceptions.

    And if you want to use this class, there are only three options:
    - use the fully qualified class name, including the namespace
    - use the "use" keyword to import the class into the current namespace
    - alias the class to another namespace using class_alias()
  • @Harro 

    class name Tokenexpiredexception;
    namespace \controller\rest\exceptions;
    file path: /fuel/classes/controller/rest/exceptions/tokenexpiredexception.php

    I see, so it will be the following?
    - use the fully qualified class name, including the namespace
    Option 1) 
    throw new \Controller\Rest\Exceptions\Tokenexpiredexception();

    - use the "use" keyword to import the class into the current namespace
    Option 2)
    use \Controller\Rest\Exceptions\Tokenexpiredexception;
    throw new Tokenexpiredexception();

    or

    Option 3)
    use \Controller\Rest\Exceptions;
    throw new Exceptions\Tokenexpiredexception();

    - alias the class to another namespace using class_alias()
    Option 4)
    class_alias('\Controller\Rest\Exceptions\Tokenexpiredexception', 'Tokenexpiredexception');
    throw new \Tokenexpiredexception();

    So I guess the best way to import all classes from same namespace (avoid import each class from same namespace one by one) is to use option 3?
  • HarroHarro
    Accepted Answer
    Option 3 is invalid, you can not import a namespace in PHP, only classes.

    Option 4 is something to avoid if you want to keep your code maintainable. So left are options 1 and 2.

    I personally am in favour of option 1. More typing, but looking at the code makes it immediately clear which class you're accessing.

    Also, what is the point of namespacing your code if you then import all classes into the same namespace again? The main reason for namespacing is grouping and collision avoidance, which you negate if you start importing everything.

    But in the end, it's a personal choice.
  • I was thinking in the way how I was using namespace in C# :)
    I would import all the classes into same namespace, while avoid same name collision:

    So say in C# way (I know won't work in PHP), I would:
    use \Controller\Rest\Exceptions;
    throw new Tokenexpiredexception(); //My rest exception
    throw new InvalidArgumentException(); // Standard exception
    throw new \Controller\Rest\Exception\InvalidArgumentException(); //In case of same name collision happen.

    What I wanted to do is grouping related classes and file into same namespace and import them like package.
    So Rest controller will able to call rest exceptions without defining full namespace path every time, while I know rest controller will use rest exceptions.
    Less code is more readable for me, I don't like reading a long long exception line :)

    By the way, I tried the option 3 is valid and running.
    But strange, I don't see any example in PHP manual doing so.
    The closing one I see is
    namespace foo{
      class 
    Cat 
        static function 
    says() {echo 'meoow';}  } 
    }
    namespace{        // No Namespace: global code
      
    use foo as feline;
      echo 
    feline\Cat::says()
    }
  • How do you manage to import a namespace (which is option 3)? Which PHP version? Can you post your exact test code at http://bin.fuelphp.com and post the link here?

    I tried on 5.6.12, and there it really doesn't work, your example fails with

    ErrorException [ Fatal Error ]:
    Class 'Controller\Tokenexpiredexception' not found
  • Wierd that won't work on 5.6.12... I have same php version 5.5.27 on both my production and development machine and they both runs fine.  
    PHP Version 5.5.27
    FuelPHP 1.7.2

    Here is my code:
    \fuel\app\classes\controller\test.php

    In case if you need the configuration file.
    And just in case if you need to know what exact package I used:
    php55u.x86_64           5.5.27-1.ius.centos6
    php55u-bcmath.x86_64    5.5.27-1.ius.centos6
    php55u-cli.x86_64       5.5.27-1.ius.centos6
    php55u-common.x86_64    5.5.27-1.ius.centos6
    php55u-dba.x86_64       5.5.27-1.ius.centos6
    php55u-debuginfo.x86_64 5.5.27-1.ius.centos6
    php55u-devel.x86_64     5.5.27-1.ius.centos6
    php55u-embedded.x86_64  5.5.27-1.ius.centos6
    php55u-enchant.x86_64   5.5.27-1.ius.centos6
    php55u-fpm.x86_64       5.5.27-1.ius.centos6
    php55u-gd.x86_64        5.5.27-1.ius.centos6
    php55u-gmp.x86_64       5.5.27-1.ius.centos6
    php55u-imap.x86_64      5.5.27-1.ius.centos6
    php55u-interbase.x86_64 5.5.27-1.ius.centos6
    php55u-intl.x86_64      5.5.27-1.ius.centos6
    php55u-ioncube-loader.x86_64
    php55u-ioncube-loader-debuginfo.x86_64
    php55u-ldap.x86_64      5.5.27-1.ius.centos6
    php55u-litespeed.x86_64 5.5.27-1.ius.centos6
    php55u-mbstring.x86_64  5.5.27-1.ius.centos6
    php55u-mcrypt.x86_64    5.5.27-1.ius.centos6
    php55u-mssql.x86_64     5.5.27-1.ius.centos6
    php55u-mysqlnd.x86_64   5.5.27-1.ius.centos6
    php55u-odbc.x86_64      5.5.27-1.ius.centos6
    php55u-opcache.x86_64   5.5.27-1.ius.centos6
    php55u-pdo.x86_64       5.5.27-1.ius.centos6
    php55u-pear.noarch      1:1.9.5-2.ius.centos6
    php55u-pecl-apcu.x86_64 4.0.7-4.ius.centos6
    php55u-pecl-apcu-debuginfo.x86_64
    php55u-pecl-apcu-devel.x86_64
    php55u-pecl-geoip.x86_64
    php55u-pecl-geoip-debuginfo.x86_64
    php55u-pecl-igbinary.x86_64
    php55u-pecl-igbinary-debuginfo.x86_64
    php55u-pecl-igbinary-devel.x86_64
    php55u-pecl-imagick.x86_64
    php55u-pecl-imagick-debuginfo.x86_64
    php55u-pecl-jsonc.x86_64
    php55u-pecl-jsonc-debuginfo.x86_64
    php55u-pecl-jsonc-devel.x86_64
    php55u-pecl-lzf.x86_64  1.6.3-1.ius.centos6
    php55u-pecl-lzf-debuginfo.x86_64
    php55u-pecl-memcache.x86_64
    php55u-pecl-memcache-debuginfo.x86_64
    php55u-pecl-memcached.x86_64
    php55u-pecl-memcached-debuginfo.x86_64
    php55u-pecl-mongo.x86_64
    php55u-pecl-mongo-debuginfo.x86_64
    php55u-pecl-pthreads.x86_64
    php55u-pecl-pthreads-debuginfo.x86_64
    php55u-pecl-redis.x86_64
    php55u-pecl-redis-debuginfo.x86_64
    php55u-pecl-xdebug.x86_64
    php55u-pecl-xdebug-debuginfo.x86_64
    php55u-pgsql.x86_64     5.5.27-1.ius.centos6
    php55u-process.x86_64   5.5.27-1.ius.centos6
    php55u-pspell.x86_64    5.5.27-1.ius.centos6
    php55u-recode.x86_64    5.5.27-1.ius.centos6
    php55u-snmp.x86_64      5.5.27-1.ius.centos6
    php55u-soap.x86_64      5.5.27-1.ius.centos6
    php55u-suhosin.x86_64   0.9.38-1.ius.centos6
    php55u-suhosin-debuginfo.x86_64
    php55u-tidy.x86_64      5.5.27-1.ius.centos6
    php55u-xml.x86_64       5.5.27-1.ius.centos6
    php55u-xmlrpc.x86_64    5.5.27-1.ius.centos6

    Output of test.php's get_index():
    Exception: Token Exception!Exception: Invalid Token Exception!
  • Ah, but that is not importing the namespace, but aliasing it.

    I looked at and tried:

    use \Controller\Rest\Exceptions;
    throw new Tokenexpiredexception(); //My rest exception

    While you do:

    use \Controller\Rest\Exceptions;
    throw new Exceptions\Tokenexpiredexception(); //My rest exception

    And that will work, yeah.
  • Oops, I meant I wish I can do:

    use \Controller\Rest\Exceptions;
    throw new Tokenexpiredexception(); //My rest exception

    Like what Java/C# does.  I know it doesn't work in PHP, sorry for misleading you :(

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

In this Discussion