Trying to understand how namespace in php works and am stuck.
This below is the architecture of the project.
Class: Loader.php (suppose to load controller/model/ library but for now gibberish test codes)
namespace system\core;
class Loader
{
public function index()
{
echo 'loader';
}
public function controller($pathtocontroller)
{
// Echo path to the controller
echo $pathtocontroller;
}
}
index.php
require 'system/core/Loader.php';
require 'system/core/BaseController.php';
require 'app/controller/common/HomeController.php';
use system\core;
use app\controller;
$loader = new \system\core\Loader();
$loader->controller(app\controller\common\HomeController);
and this is the error I get
Fatal error: Undefined constant 'app\controller\common\HomeController'
in C:\xampp\htdocs\psrstd\index.php on line 20. Lin 20 on index is $loader->controller(app\controller\common\HomeController);
Expected Result: app/controller/common/HomeController
in case you wondering what's in there at the HomeController (again gibberish test code)
namespace app\controller\common;
use system\core\BaseController;
class HomeController extends BaseController
{
public function index()
{
echo 'home';
}
}
you are passing a constant type to your controller method,
you are aiming to pass an object [ dependency injection ] so you will need to instantiate your argument like :
$loader->controller(new \app\controller\common\HomeController);
otherwise you may send this argument as a string like :
$loader->controller("\\app\\controller\\common\\HomeController");
and instantiate that object within your method [ as a factory method ]
public function controller($pathtocontroller)
{
// new $pathtocontroller and so on
}
Further reading :
What is Dependency Injection?
Factory design pattern
Related
I have a php 5.4 application where I am trying to implement namespaces.
I have a models folder with a model Admin.php in it.
<?php
namespace models;
class Admin extends Model
{
public function getAllContent($lang)
{
return some stuff ...
}
}
I have an adminController.php where I do this:
<?php
use models\Admin;
class adminController extends Controller
{
function index()
{
$variable = Admin::getAllContent($this->lang);
}
}
I get this error
Fatal error: Class 'models\Admin' not found in /.../controllers/adminController.php on line 22
this is line 22 : $variable = Admin::getAllContent($this->lang);
I have a tester class and I'm trying to use the global helper method base_path(), but I get the error below:
Error: Call to undefined method Illuminate\Container\Container::basePath()
/myproject/vendor/laravel/framework/src/Illuminate/Foundation/helpers.php:182
/myproject/tests/Feature/DataCsvSeedTest.php:31
/myproject/vendor/phpunit/phpunit/src/TextUI/Command.php:195
/myproject/vendor/phpunit/phpunit/src/TextUI/Command.php:148
Looks like helper.php in Laravel calls basePath(), and can't find it. Am I missing a namespace or some other setting for the global helper functions? Using Laravel 5.5.
<?php
namespace Tests\Feature;
use Tests\TestCase;
class DataCsvSeedTest extends TestCase
{
public function setUp()
{
$baseDir = base_path();
print "basedir = ". $baseDir;
}
}
Ah... This is a testClass,
class DataCsvSeedTest extends TestCase
{
public function setUp()
{
parent::setUp();
$baseDir = base_path();
print "basedir = ". $baseDir;
}
}
when you are overriding setUp() method don't forget to call the parent::Setup(), which will bootstrap the application.
I am trying to create an ACL component as a service, for a multi-module PhalconPHP application. When I call the ACL component from the Controller Base, I am getting an error that I can't re-declare the ACL class.
Any ideas how to fix it, and understand the logic of why it is re-initialized again?
Fatal error: Cannot declare class X\Acl\Acl because the name is already in use in C:\xampp\htdocs\x\app\common\Acl\Acl.php on line 12
Update:
If I changed everything to "Pacl" then it works. I assume there might be a mixup with the PhalconPHP namespace. I am either not using the namespaces properly, or there's a bug in PhalconPHP 2.1 Beta 2.
/app/common/Acl/Acl.php
namespace X\Acl;
use Phalcon\Mvc\User\Component;
use Phalcon\Acl;
use Phalcon\Acl\Role as AclRole;
use Phalcon\Acl\Resource as AclResource;
/*
* ACL component
*/
class Acl extends Component {
private function initialize() {
}
public function isAllowed() {
die('called');
}
}
/app/front/controllers/ControllerBase.php
namespace X\Front\Controllers;
use Phalcon\Session as Session;
use Phalcon\Mvc\Controller;
use Phalcon\Mvc\Dispatcher;
class ControllerBase extends Controller {
public function beforeExecuteRoute(Dispatcher $dispatcher) {
//$this->acl = $this->getDI()->get("acl");
var_dump($this->acl->isAllowed()); //same behavior in both case
}
}
/app/front/Module.php
namespace X\Front;
use Phalcon\DiInterface;
use Phalcon\Mvc\Dispatcher;
use X\Acl\Acl as Acl;
class Module {
public function registerAutoloaders() {
$loader = new \Phalcon\Loader();
$loader->registerNamespaces(array(
'X\Front\Controllers' => __DIR__ . '/controllers/',
'X\Front' => __DIR__,
'X' => __DIR__ . '/../common/'
));
$loader->register();
}
public function registerServices(DiInterface $di) {
$di['acl'] = function() {
return new Acl();
};
}
}
This is not Phalcon issue. Look closely at your code:
namespace X\Acl;
use Phalcon\Acl;
class Acl extends ... {
}
What Acl interpreter should use? X\Acl\Acl or Phalcon\Acl?
The same error you get for example for the following code
namespace My\Awesome\Ns;
use Some\Name; # Name 1
class Name # Name 2
{
}
I have write a router.test.php file:
class RouterTest extends PHPUnit_Framework_TestCase
{
public function setUp()
{
require_once '../router.class.php';
}
public function testUnit()
{
$this->assertEquals(true, true);
}
}
... for simply test if my PHPUnit library is working correctly. But when I type phpunit router.test.php in my console I get this error message: Fatal error: Trait 'Core' not found in C:\xampp\htdocs\_Framework\ver_3\libraries\router\router.class.php on line 23
... my Router class is working correctly and my Autoloader automatically include trait (named Core) inside my Router class.
Where is the problem?
My Autoloader register method looks like:
public static function register()
{
return spl_autoload_register(
__CLASS__ . '::load'
);
}
... I use this method in my index.php file, should I write another autoloader for PHPUnits?
I have include necessary files in the setUp method, now the class looks like that:
<?php
use Framework\Libraries\Configuration\Configuration;
use Framework\Libraries\Autoload\Autoloader;
class RouterTest extends PHPUnit_Framework_TestCase
{
public function setUp()
{
require '../../core.trait.php';
require '../../configuration/configuration.class.php';
require '../../autoload/autoloader.class.php';
Configuration::set('files', [
require '../../../configuration/framework.configuration.php',
require '../../../configuration/autoloader.configuration.php',
require '../../../configuration/router.configuration.php',
]);
Autoloader::set('prefixes', ['Framework']);
Autoloader::set('extensions', ['.class.php', '.trait.php']);
Autoloader::register();
require_once '../router.class.php';
}
public function testUnit()
{
$this->assertEquals(true, true);
}
}
... an I get a new error message: E Time: 109 ms, Memory: 1.75Mb There was 1 error, but I can't get the error message. I think it's because Autoloader can't load files because of wrong path.
No it won't load index file automatically. So you need to include all your relevant class in your unit test class by adding include_once('AutoLoader.php'); in or another way is to create a bootstrap.php file & include all classes you need in all the PHPUnit Test class.
Reference.
I have a CodeIgniter spark defining&autoloading a class libraries/Nci_nicecontroller.php:
class Nci_nicecontroller extends CI_Controller {
//...
}
//autoloaded using $autoload['libraries'][]='nci_nicecontroller';
now I want to use Nci_nicecontroller in my application's controller, e.g.:
class Welcome extends Nci_nicecontroller {
//...
}
//autoloaded using $autoload['sparks'][]='nci-extensions/0.0.4';
obviously, I can't just $this->load->spark in my controller's constructor, because it's required on class extension.
when not using sparks, I just put the Nci_nicecontroller in a core/MY_Controller.php, but with sparks, this won't work.
I tried autoloading the spark in my application, which didn't work.
Then I tried:
get_instance()->load->spark('nci-extensions/0.0.4');
in the header of controllers/welcome.php, which gives me following errors:
Severity: Notice
Message: Trying to get property of non-object
Filename: controllers/welcome.php
Line Number: 2
--and--
Fatal error: Call to a member function spark() on a non-object in
C:\xampp\htdocs\CodeIgniter_demo\application\controllers\welcome.php on line 2
what shall I do?
Try to do something like that:
class Wellcome extends CI_Controller {
protected static $_nci = null;
public function __construct(){
parent::__construct();
$this->_nci = $this->load->spark('nci-extensions/0.0.4');
}
public function index(){
$result = $this->_nci->getSomething();
echo $result;
}
}