Tim567
Tim567

Reputation: 815

How do I execute a function on a string PHP

While i was working on a school project I ran into a problem.

I have made an Router class where it get the right files, but I am getting the following error:

Fatal error: Method mvc\App::__toString() must not throw an exception, caught Error: Call to a member function getHTML() on string in /opt/lampp/htdocs/School/testPHP/mvc/public/index.php on line 0

The echo returns the correct file path so that is not the issue I'm running into.

I think the issue is because I try to execute an function into a string.

Does anyone know how I can fix my issue?

App Class:

<?php
namespace mvc;

class App{
    private $router;

    public function __construct(){
        $this->router = new \mvc\Router();
    }


    public function __toString(){
        try {
            echo $this->router->getView(); //this returns the correct file path 
            return $this->router->getView()->getHTML();
        } catch (Exception $e) {
            return $e.getMessage;
        }
    }
}
?>

Router.php:

<?php
namespace mvc;

class Router{

private $route;
private $view;
private $controller;
private $model;

public function __construct(){
    require_once(LOCAL_ROOT. "php/Routes.php");
    if (isset($_GET['route'])){
        $this->route = explode("/" , $_GET['route']);
    }
    $route = isset($routes[$this->getRoute()])? $this->getRoute() : DEFAULT_ROUTE;
    $this->controller = "\\controllers\\". $routes[$route]['controller'];
    $this->view = "\\views\\". $routes[$route]['view'];
    // $model = "\\models\\". $routes[$route]['model'];
}

private function getRoute(){
    return count($this->route) > 0 ? $this->route[0] : DEFAULT_ROUTE;
}
public function getView(){
    return $this->view;
}
}
?>

Routes.php

<?php
define("DEFAULT_ROUTE", "home");
$routes = array(
"home" => array(
    "view" => "HomeView",
    "controller" => "HomeController",
),
"form" => array(
    "view" => "FormView",
    "controller" => "FormController",
),
"test" => array(
    "view" => "TestView",
    "controller" => "TestController",
),
)
?>

TestView.php

<?php
namespace views;

class TestView extends \mvc\View{
public function getHTML(){
    // return 'dit is testView';
    $klik = $this->controller->getGetData("klik");
    $output = "";
    $output .= "<h1>".$klik++ ."</h1>";
    $output .= "<a href=\"test?klik=$klik\">klik</a>";
    $output .= "<br>";
    return $output;
}
}

?>

Upvotes: 1

Views: 199

Answers (1)

Mark
Mark

Reputation: 1872

The Problem:

Okay so the problem is that you're making a call to a function from a string.

This is the getView method in the Router class:

public function getView(){
    return $this->view;
}

This method returns a string:

$this->view = "\\views\\". $routes[$route]['view'];

You are then trying to call a method from this string:

return $this->router->getView()->getHTML();

The Potential Solution:

Obviously you're trying to access the getHTML method in the TestView class, so without knowing more about your setup, it's hard to get exact, but I'll take a guess at the following and you can guide me in the right direction in the comments.

If you change the constructor in your App class to this:

public function __construct(){
    $this->router = new \mvc\Router();
    $this->testView = new \views\TestView();
}

Then you can change your __toString method to the following:

echo $this->router->getView(); //this returns the correct file path 
return $this->testView->getHTML();

I'm not sure why you'd echo and then return, usually it's one or the other, but if you elaborate more on your expected output I can help you some more, or hopefully my explanation has given you enough to work from.


Solution:

After reading your comments, it looks like you want to instantiate the class from the result of the getView method, you can do this by setting the result into a variable and calling a new class from that string and THEN calling the method from that class.

$class = $this->router->getView();
$class = new $class;

return $class->getHTML();

Upvotes: 1

Related Questions