5

I have been creating custom libraries for a project that i've been porting over into the CI framework and I ran into an issue where certain classes have identical names.

To circumvent this issue, I tried implementing namespaces to no avail. I've been doing research and I know in the past this may not have been possible but with the newer version of PHP, I was wondering if there was a way to do this or if I was doing it correctly.

CI Version: 2.1.4 PHP Version: 5.4.12

Here is a demo of my setup:

application/libraries/class1.php

<?

class class1{
   public function __construct()
    {
        $CI =& get_instance();

        $CI->load->library('foo/class2.php');
    }
}
?>

application/libraries/foo/class2.php

<?

namespace foo

class class2{

    function bar(){

    }

} 

?>

When I run my CI application, I will get the following error:

Non-existent class: class2

Thanks for any help.

ssj16
  • 51
  • 1
  • 1
  • 2
  • 1
    i did a quick search on github https://github.com/EllisLab/CodeIgniter/issues/2820 – cartalot Mar 14 '14 at 18:12
  • Use composer/PSR-0 and require composer autoload in CI index.php. I use "Whoops" and "Monolog" via this method! – Philip Mar 15 '14 at 00:41
  • Alex wrote an answer that worked for me. [Here's the answer.](https://stackoverflow.com/a/49461228/337306) – desbest Dec 13 '20 at 06:00

5 Answers5

2

From what I've found, if the library file doesn't have

if ( ! defined('BASEPATH')) exit('No direct script access allowed');

as the first line of code it won't load the library.

But then the namespace declaration needs to be above that.

CodeIgniter was written for PHP4 whereas namespace is PHP5.

There's more information in this thread: Namespace in PHP CodeIgniter Framework

Community
  • 1
  • 1
david_nash
  • 678
  • 7
  • 14
  • 3
    This is incorrect. That line of code has no relevance to what is loaded in CI, that line of code is to prevent users from loading that file directly without going through the CI framework. – tmarois Aug 10 '16 at 17:55
  • Well, i`m actually having a issue exactly like David says. The namespace must be the first line of code. But codeigniter wants the defined base path to be the first line of code. So it the one or the other, but in either cases an error. – Esocoder Dec 21 '18 at 00:37
2

Codeigniter does not support namespaces in 2.x and 3.x, what I would usually do especially with 3rd party libraries is load them in manually. Using your example, I would do:

// you can still manually load in libraries like this
require_once(APPPATH.'libraries/foo/class2.php');

class class1 {

   public function __construct()
    {
        $CI =& get_instance();

        // instantiate the class2 and make it available for all of class1 methods
        $this->class2 = new foo/class2();
    }

}

Just because it's a framework doesn't prevent you from using core php functionality, most people forget that you can still do normal php methods to achieve the same results.

tmarois
  • 2,424
  • 2
  • 31
  • 43
  • Note: `=&` is a violation of the PSR-12 coding standard. More info: https://stackoverflow.com/a/63914758/2943403 – mickmackusa Oct 14 '20 at 02:48
2

This issue arose in a personal project while attempting to use some third-party libraries.

To get around it (without modifying the source files), I made a "bootstrap" class that loaded and extended the core library:

<?php

require_once(APPPATH.'libraries/foo/class2.php');

class class2 extends foo\class2 {}

This "bootstrap" class can then be loaded and used as if it were the extended one:

$this->load->library("class2");

$this->class2->bar(); // same as foo\class2->bar();
AlbinoDrought
  • 986
  • 17
  • 24
0

The issue is that 'load' doesn't take into account namespaces as far as I know.

which means that load('foo/class2') will look for the folder 'foo' inside the libraries folder.

you include the files normaly, when you create a new object you use the 'foo/bar'.

I'm not if the load class supports that though, You might need to simply create a new object manually(which is what the load class does anyway, it includes the file and creates a new object).

Patrick
  • 3,289
  • 2
  • 18
  • 31
0

I'll quote an answer from Alex.


I know I've answered this question before I just can't find where and don't know what to search. So here it is: Codeigniter can only load single php file libraries (excluding drivers which is a different thing entirely). To load this kindof library (namespaced) you have to use something like: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader-examples.md (class example).

Let's call it Autoloader_psr4 and save it in libraries (modify the class declaration to match this name verbatim (e.g. Autoloader_psr4). Remove the namespace declaration in the class so it looks like: https://pastebin.com/NU8Rbp7Y

Let's also move all the files in src/randomorg/ or src/foo to just be in a folder in third_party called RandomOrg or foo e.g. application/third_party/RandomOrg or application/third_party/foo. Your folder should look like the contents here: https://github.com/defiant/randomorg/tree/master/src/randomorg

Usage:

$this->load->library('autoloader_psr4');
$this->autoloader_psr4->register();
$this->autoloader_psr4->addNamespace('RandomOrg', APPPATH . 'third_party/RandomOrg');
$random = new \RandomOrg\Client(); // or whatever...
desbest
  • 4,746
  • 11
  • 51
  • 84