0

I am trying to understand how I can change the way the routing works in this tutorial that I did.

Currently, if you go to a contact page for example, the url looks like:

mysite.com/pages/contact

I understand that I have a views folder with another folder called 'pages' in it, and I have a pages controller that sends the data to that view:

$this->view('pages/contact', $data);

But I don't want it to look like that. I would rather it was just mysite.com/contact without having to have the /pages/

I am not sure what code would be required to post here so I am going to post what I think will be helpful.

In my root folder with my index.php I have a .htaccess file

<IfModule mod_rewrite.c>
 RewriteEngine on
 RewriteRule ^$ public/ [L]
 RewriteRule (.*) public/$1 [L]
</IfModule>

In my public folder I have another .htaccess

<IfModule mod_rewrite.c>
 Options -Multiviews
 RewriteEngine On
 RewriteBase /jonomvc/public
 RewriteCond %{REQUEST_FILENAME} !-d
 RewriteCond %{REQUEST_FILENAME} !-f
 RewriteRule ^(.+)$ index.php?url=$1 [QSA,L]
 </IfModule>

In my pages controller I have:

public function contact() {

        $data = [

            'title' => 'Contact us'
        ];

        $this->view('pages/contact', $data);
}

And this is my core class:

class Core {

    protected $currentController = 'Pages';
    protected $currentMethod = 'index';
    protected $params = [];

    public function __construct() {
        $url = $this->getUrl();

        // Look in Controllers for first value
        if(file_exists('../app/controllers/' . ucwords($url[0]) . '.php')) {
            //if exists, set as controller
            $this->currentController = ucwords($url[0]);
            // Unset zero index
            unset($url[0]);
        }

        // Require the controller
        require_once '../app/controllers/' . $this->currentController . '.php';

        // Instantiate controller
        $this->currentController = new $this->currentController;

        // Check for second part of url
        if(isset($url[1])) {

            $url[1] = str_replace('-', '_', $url[1]);

            // check to see if method exists in controller
            if(method_exists($this->currentController, $url[1])) {
                $this->currentMethod = $url[1];
                // Unset 1 index
                unset($url[1]);
            }   
        }

        // Get params
        $this->params = $url ? array_values($url) : [];

        // Call a callback with array of params
        call_user_func_array([$this->currentController, $this->currentMethod], $this->params);
    }

    public function getUrl() {
        if(isset($_GET['url'])) {
            $url = rtrim($_GET['url'], '/');
            $url = filter_var($url, FILTER_SANITIZE_URL);
            $url = explode('/', $url);
            return $url;
        }

    }
}

I created the controller in the controllers folder called 'Contact.php'

class Contact extends Controller {

    public function __construct() {


    }

    public function contact() {

        $data = [

            'title' => 'Contact us'
        ];

        $this->view('contact', $data);
    }
}

If the contact page was sitting inside my 'pages' folder, inside of my 'views' folder then I would have used:

$this->view('pages/contact', $data);

But since I don't want the /pages/ part, I put the contact.php into the root of the 'views' folder instead of 'views/pages' folder, but that does't seem to work e.g.:

$this->view('contact', $data);

The error is:

Warning: call_user_func_array() expects parameter 1 to be a valid callback, class 'Contact' does not have a method 'index' in /Applications/MAMP/htdocs/mysite/app/libraries/Core.php on line 54

Line 54:

call_user_func_array([$this->currentController, $this->currentMethod], $this->params);
tereško
  • 58,060
  • 25
  • 98
  • 150
user8463989
  • 2,275
  • 4
  • 20
  • 48
  • Stop relaying on `explode()` to pars the URL. Instead you should use regular expressions (explained in [this post](https://stackoverflow.com/a/19309893/727208)), where, for each matching route, you can set the "default" or "silent" parameters. Or, if it's an option, you should use standalone routing components like [this](http://symfony.com/doc/current/components/routing.html) or [this](https://github.com/nikic/FastRoute). – tereško Nov 26 '17 at 13:10

1 Answers1

0

In CodeIgniter, you to configure your routes.php file in application>config and just simply do this. See the image and it just simply says that if controllername/filename is called then you should only display the filename only instead of controllername/filename.

Secondly, if you want to do it via .htaccess file just do the followings:

RewriteRule ^new/registration?$ registration.php

This says that if the mysite.com/new/registration is called then you should load registration.php

Muhammad Omer Aslam
  • 22,976
  • 9
  • 42
  • 68