Reputation: 815
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
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