ohiock
ohiock

Reputation: 646

PHP - Proper way to extend class

I am currently working on a mini 'framework' and I am having some difficulties. I'm attempting this in order to strengthen my understanding of basic concepts utilized in most MVC's (At least from what I have seen). So yes, I do understand that using a framework may be easier and not everything that I am doing is ideal. I am just trying to learn more.

So I have 2 files that I am currently working with.

FrontController.php

<?php   
class FrontController {
    public function __construct() {
        $this->go(); // RUNS GO FUNCTION UPON LOADING
    }

    public function go() {          
        $url = $_SERVER['REQUEST_URI']; // GRABS URL
        $action = explode("/", $url); // SPLITS UP URL INTO SECTIONS

        $object = ucfirst($action[2]) . "Controller"; // SETS 2ND SECTION OF URL TO UPPERCASE AND IDENTIFIES THE CONTROLLER
        $file = APP_DIR . "/" . $object . ".php"; // IDENTIFIES THE FILE THAT WILL BE USED

        if(!is_file($file)){ // DETERMINES IF FILE EXISTS
            $this->fail(); // IF NOT, FAILS
        } else {
            require_once $file; // IF EXISTS, PULLS IT IN
            $method = ucfirst($action[3]); // THE 3RD SECTION OF THE URL IS THE METHOD
            $controller = new $object(); // CREATE INSTANCE OF THE IDENTIFIED OBJECT

            if(!method_exists($controller, $method)){ // DETERMINES IF METHOD EXISTS IN THE CLASS
                $this->fail(); // IF NOT, FAILS
            }

            $controller->$method(); // RUN METHOD
            exit(0);
        }
    }

    public function fail() {
        echo "<h1>Failure</h1>"; // FAILURE MESSAGE
    }
}

/application/BaseController.php

<?php   
class BaseController {
    public function __construct() {
        $this->session();
    }

    public function session() {
        session_start();
        $_SESSION['is_logged_in'] = 1;
        echo "hi";
    }
}

So what I would like to be able to do is extend the BaseController with the FrontController. I figured that extending the BaseController would allow me to add common functionality to my entire application. The problem is that I am not certain how to do this properly. I know that I need to 'require' BaseController.php into FrontController.php somehow, but I have seen many different ways and I want to know which is most correct.

What I have tried is simply adding 'require_once("/application/BaseController.php");' to the top of FrontController.php and then extending the FrontController class, but this isn't working (blank page), and from what I have read, it is not the best way.

I read into __autoload() but I do not understand how to use it effectively. Do I just put this at the top of my FrontController.php file and extend my class after that?

So, to summarize, I would like to extend my FrontController class (and other future classes, when necessary) with my BaseController. I would just like some advice for how to accomplish this task effectively. It may even be possible that the way I have this thought out is ass backwards, and if that is the case, please let me know!!

Upvotes: 1

Views: 553

Answers (2)

user4962466
user4962466

Reputation:

To give a better structure on your framework and your future project I recommend you to use some tricks and best practices.

  • Namespacing: for better organizing your code and your classes
  • Autoloading: for autoloading your classes in a smart way

Namespacing http://php.net/manual/en/language.namespaces.php and autoloading http://php.net/manual/en/language.oop5.autoload.php can be viewed on official documentation.

To better understanding you can take a look here

  1. Define and register autoloading function

    function autoload($class) {
        preg_match('/^(.+)?([^\\\\]+)$/U', ltrim( $class, '\\' ), $match ) );
        require str_replace( '\\', '/', $match[ 1 ] ). str_replace( [ '\\', '_' ], '/', $match[ 2 ] ). '.php';
    }
    
    spl_autoload_register('autoload');
    
  2. Use namespacing around your application

Base Controller

    <?php namespace App\Controller;

    class BaseController { ... }

FrontController

    <?php namespace App\Controller;
    use App\Controller\BaseController as BaseController;

    class FrontController extends BaseController { ... }

Upvotes: 1

Richard Testani
Richard Testani

Reputation: 1482

You extend classes like:

<?php
class FrontController extends BaseController {
 ..code...
}


?>

__autoload is a magic method which loads classes automatically. So you could add this in your FrontController as an example and load your controllers as needed. Read about autoloading classes here:

http://php.net/manual/en/language.oop5.autoload.php

Also, take advantage of SPL in PHP which will help define your application better.

Upvotes: 1

Related Questions