Autoload of controllers using namespace

0

I'm trying to give a restructured in a personal microframework, before I did not use much pattern in the design structure, now I've thrown my whole backend in the source folder, and I'm using namespaces to separate the code. I'm having trouble doing autoload , I want to give new Crontrolador() without first having to use use \Controllers\Controlador .

I've never really understood this part so I've come to ask for help, currently in my Core class I have the following method which is responsible for doing some validations and calling the controller:

private function addControllerAndModel($class, $method, $page = false)
{
    $class = ucfirst($class);
    $controller = "{$class}Controller";

    if(file_exists(__DIR__."/../../Controllers/{$controller}.php")) {

        echo "Controller existe<br>";
        if($page)
            $this->importRels(Relationships::get('*'));

        $this->importRels(Relationships::get($class));

        $instance = new $controller();

        if($page) {
            if(count($_POST)) {
                if($_POST['token'] === Session::get('token') or in_array($_POST['token'], Settings::get('allowsAjax'))) {
                    Session::set('token', false);
                    Saved::create();
                    $method = "{$method}Posted";
                }
                else {
                    Errors::display('Token inválido', DOMAIN);
                    exit();
                }

            }
            else {
                if(!Session::get('token'))
                    Session::set('token', md5(crypt(time(), '$1$rasmusle$')));
                $method = "{$method}Deed";
            }
        }


            $instance->{$method}();
       // else
            //Errors::display("Método não encontrado [{$controller}/{$method}]");
    }
    //else
        //Errors::display("Controlador não encontrado [{$controller}]");

    echo $this->controller . " / " . $this->method;
}

In short, I see if there is a requested driver file, if there is one I will import the Models related to that controller, and then I will instantiate the controller, after that I have some security controls, and finally I call the desired method. p>

Currently the error in line 126 (% with%):

  

Fatal error: Uncaught Error: Class 'HomeController' not found in   /home/leonardo/www/tcc/newframework/source/Kernel/Kernel/Core.php:126

The following is the folder structure of my project:

Project

--binary
--public
----js
----css
----librarys
----views
--source
----Controllers
------MeuControlador.php
----Kernel
------Kernel
--------Core.php
----Models
------MeuModel.php
--settings
--third
--trials

The quoted function is present in Core.php, and the controllers are two levels behind and in the Controllers folder. I do not understand how to do such autoloader with namespaces, so the only attempt I have is this method above.

An example controller:

<?php
/**
 * Created by PhpStorm.
 * User: leonardo
 * Date: 17/09/16
 * Time: 14:52
 */

namespace Controllers;

class HomeController extends Kernel\Control\Controller
{
    public function startDeed()
    {
        echo "Hello World!!";
    }

}

Is it possible to give $instance = new $controller(); without declaring new HomeController() ? I've tried using:

$instance = \Controllers\{$controller}();

But it did not work: (

    
asked by anonymous 17.09.2016 / 20:41

1 answer

2

The problem is how you instantiated your class.

Do not mix the declaration of the object with strings , it will not work.

Instead, concatenate the class name with the expected namespace in a string :

<?php

namespace Legumes {

    class Batata {

    }

}

// volta para o namespace global
namespace {
    $classe = 'Batata';

    // Cuidado especial com a barra invertida, ela é utilizada como escape
    $fqn = "\Legumes\{$classe}";

    $instance = new $fqn;

    var_dump($instance);
}

See running .

    
17.09.2016 / 21:06