bekommen Ich habe diese Router.php im Kern meiner Anwendung.Router-Parameter mit dem Registry-Muster
router.php
<?php
final class Router
{
protected $routes = [];
protected $params = [];
public function add($route, $params = [])
{
$route = preg_replace('/\//', '\\/', $route);
$route = preg_replace('/\{([a-z]+)\}/', '(?P<\1>[a-z-]+)', $route);
$route = preg_replace('/\{([a-z]+):([^\}]+)\}/', '(?P<\1>\2)', $route);
$route = '/^' . $route . '$/i';
$this->routes[$route] = $params;
}
public function getRoutes()
{
return $this->routes;
}
public function match($url)
{
foreach ($this->routes as $route => $params) {
if (preg_match($route, $url, $matches)) {
foreach ($matches as $key => $match) {
if (is_string($key)) {
$params[$key] = $match;
}
}
$this->params = $params;
return true;
}
}
return false;
}
public function getParams()
{
return $this->params;
}
public function dispatch($url)
{
$url = $this->removeQueryStringVariables($url);
if ($this->match($url)) {
$controller = $this->params['controller'];
$controller = $this->convertToStudlyCaps($controller);
$controller = $this->getNamespace() . $controller;
if (class_exists($controller)) {
$controller_object = new $controller($this->params);
$action = $this->params['action'];
$action = $this->convertToCamelCase($action);
if (is_callable([$controller_object, $action])) {
$controller_object->$action();
} else {
echo "Method $action (in controller $controller) not found";
}
} else {
echo "Controller class $controller not found";
}
} else {
echo 'No route matched.';
}
}
protected function convertToStudlyCaps($string)
{
return str_replace(' ', '', ucwords(str_replace('-', ' ', $string)));
}
protected function convertToCamelCase($string)
{
return lcfirst($this->convertToStudlyCaps($string));
}
protected function removeQueryStringVariables($url)
{
if ($url != '') {
$parts = explode('&', $url, 2);
if (strpos($parts[0], '=') === false) {
$url = $parts[0];
} else {
$url = '';
}
}
return $url;
}
protected function getNamespace()
{
$namespace = 'catalog\controller\\';
if (array_key_exists('namespace', $this->params)) {
$namespace .= $this->params['namespace'] . '\\';
}
return $namespace;
}
}
Um einen zentralen Speicher für Objekte zu implementieren, habe ich dieses Registrierungsmuster implementiert, die den Kern der Struktur ist.
registry.php
<?php
final class Registry
{
private $data = array();
public function get($key)
{
return (isset($this->data[$key]) ? $this->data[$key] : null);
}
public function set($key, $value)
{
$this->data[$key] = $value;
}
public function has($key)
{
return isset($this->data[$key]);
}
}
Die Basis/Kern-Controller ferner aufweist $ Register an seinem Konstrukt Funktion.
CoreController.php
<?php
abstract class CoreController
{
protected $registry;
public function __construct($registry)
{
$this->registry = $registry;
}
public function __get($key)
{
return $this->registry->get($key);
}
public function __set($key, $value)
{
$this->registry->set($key, $value);
}
}
Die CoreController von allen App-Controller erweitert wird, um die Eigenschaften zu erben.
Posts.php
<?php
class Posts extends CoreController
{
public function index() {
echo 'Hello from the index action in the posts controller';
}
public function addNew() {
echo 'Hello from the addNew action in the posts controller';
}
public function edit() {
echo '<p>Route parameters: <pre>'.var_dump($this->registry).'</pre></p>';
}
}
Um die Registrierung und Router instanziiert das ist das, was in der
index.php
<?php
// Instantiate registry
$registry = new \system\core\Registry();
// Database
$db = new DB(DB_HOSTNAME, DB_USERNAME, DB_PASSWORD, DB_DATABASE);
$registry->set('db', $db);
$router = new \system\core\Router();
$registry->set('router', $router);
// Add the routes
$router->add('', ['controller'=>'HomeController', 'action'=>'index']);
$router->add('posts', ['controller'=>'posts', 'action'=>'index']);
//$router->add('posts/new', ['controller'=>'posts', 'action'=>'new']);
$router->add('{controller}/{action}');
$router->add('{controller}/{id:\d+}/{action}');
$router->add('admin/{controller}/{action}');
$router->dispatch($_SERVER['QUERY_STRING']);
Nach der URL http://localhost/mvcsix/posts/1235/edit
diese ist was angezeigt wird
All dies sieht gut aus und funktioniert gut.
Irgendwie fühlt sich das nicht richtig an. Ich habe var_dumped this-> Registrierung und ich habe die Parameter der Route angezeigt, aber ich fühle, dass, um die Parameter von der Route zu erhalten, ich hätte var_dumped $ this-> router-> getParams(). Als ich var_dump $ this-> Router-> getParams(), erhalte ich einen Fehler, der sagt
Fatal error: Call to a member function get() on array in
ich das sagen, weil ich das Datenbankobjekt in der Registrierung zu und die Abfrage zu erhalten, ich $result = $this->db->query("SELECT * FROM members");
tun anzuzeigen
Warum werden die Parameter auf $ this-> registry angezeigt und nicht auf $ this-> router-> getParams(); ?
P.S. Der obige Code ist ein Stripdown des ursprünglichen Codes. Es gibt Namespaces und einige weitere Dinge, die für diesen Beitrag nicht notwendig waren.
Wie instanziieren Sie 'Posts' oder' CoreController'? Der Fehler sieht so aus, als ob Sie es als '$ controller = new Posts ([]) 'machen; und daher ist' registry 'ein Array. –