Witam. Tworzę mechanizm routingu, który ma za zadanie wywołać metodę klasy kontrolera w przypadku, gdy Router znajdzie w niej dopasowanie do ścieżki url w żądaniu GET. Wygląda to tak, że każda z metod klasy kontrolera musi zwracać tablicę, w której zawarta jest również ścieżka potrzebna do wywołania tej metody. Wszystko działa lecz problem powstaje w momencie, gdy w wywołanej metodzie kontrolera utworzę ponownie obiekt RouteCollection i wywołam metodę getallroutes() z klasy RouteCollection, z której również korzysta klasa Routera. Wtedy powstaje nieskończona pętla i na końcu wyskakuje komunikat: "Allowed memory size of 134217728 bytes exhausted (tried to allocate 262144 bytes)". Problem tkwi w metodzie getallroutes, która aby pobrać wszystkie ścieżki routingu musi pobrać informacje z metod wszystkich kontrolerów i dodać je do tworzonej tablicy routingu.
Poniżej wrzucam pliki klasy Router, Routecollection i przykłądowego kontrolera:
Router.php
<?php require 'usingclasses/RouteCollection.php'; require 'controller.php'; require 'usingclasses/RenderRouteView.php'; class Router { private $urlpath; private $request; private $dir = 'scripts/controllers/'; private $collection; public function __construct($urlpath, http://www.php.net/array $request) { $this->urlpath = $urlpath; $this->request = $request; $this->collection = new RouteCollection(); $this->collection = $this->collection->getallroutes(); //tablica routingu } /** * @return array */ private function parseurl() { $url = http://www.php.net/explode('/', $this->urlpath); $url = http://www.php.net/array_filter($url); return $url; } /** * creates Controller's and View's object matched to url path * * @return mixed|null * @throws Exception */ public function findroutecontroller() //metoda inicjująca pracę routera { foreach($this->collection as $routepath => $routename) //przetwarzanie tablicy routingu { if($routepath == http://www.php.net/implode('/', $this->parseurl())) { $viewob = new RenderRouteView($this->collection[$routepath]['view'],$this->collection[$routepath]['args']); // mało istotne return $viewob->renderview(); } } } }
<?php class RouteCollection { private $directory = 'scripts/controllers/'; private $routecollection = []; private $array = []; /** * Odpowiada za tworzenie tablicy [ścieżka/routingu => nazwa_routy] * * @return array * @throws Exception */ public function getallroutes() { foreach ($this->getdirfiles($this->directory) as $dirfile) { $ob = $this->createobjectfromdirfile($dirfile); // Tworzy dynamicznie obiekt kontrolera który chyba nie jest usuwany if(http://www.php.net/is_object($ob)) { $obmethods = $this->getobjectmethods($ob); foreach ($obmethods as $method) { // pętla z metodami aktualnie przetwarzanego kontrolera if(!$this->getrepeatemethoddata($this->array, $ob->$method())) { $this->array[$ob->$method()['route']] = $ob->$method(); // tworzenie tablicy [ścieżka/routingu => nazwa_routy] } } http://www.php.net/unset($obmethods); http://www.php.net/unset($ob); } } return $this->array; } private function getdirfiles($dir) { return scandir($this->directory); } private function createobjectfromdirfile($file) { if(http://www.php.net/is_file($this->directory.$file)) { $cutfilename = http://www.php.net/explode('.php', $file); require_once $this->directory.$file; $ob = new $cutfilename[0](); return $ob; } return null; } private function getobjectmethods($object) { $arr = []; if(http://www.php.net/is_object($object)) { $arr = get_class_methods($object); return $arr; } return $arr; } private function getrepeatemethoddata(http://www.php.net/array $array, $method) { if(!http://www.php.net/key_exists($method['route'], $array)) { } if(http://www.php.net/key_exists($method['route'], $array)) { throw new Exception('repeated keys'); } if(http://www.php.net/in_array($method['routename'], http://www.php.net/array_values($array)) == false) { } if(http://www.php.net/in_array($method['routename'], http://www.php.net/array_values($array)) == true) { throw new Exception('repeated values'); } return false; } }
<?php require 'scripts/usingclasses/CreateForm.php'; class examplecontroller extends Controller { /** * @return array * @throws Exception */ public function someactionother() { $createform = new CreateForm(); $cos = $this->getcollection(); $form = $createform ->addformfield('input', 'login', 'Podaj login') ->addformfield('input', 'haslo', 'Podaj hasło') ->addformfield('submit', 'zapisz') ->renderform(); return $this->generaterouteargs('ma', 'jakas_routa', 'a.php', ['form'=> 'aa']); } private function getcollection() { $arr = []; $dane = new RouteCollection(); $d = $dane->getallroutes(); return $d; } }
<?php require 'scripts/Router.php'; $path = !http://www.php.net/empty($_GET['path'])? $_GET['path']: null; $router = new Router($path, $_REQUEST); $router->findroutecontroller();
$ob = $this->createobjectfromdirfile($dirfile);
public function getallroutes() { $arr =[]; foreach ($this->getdirfiles($this->directory) as $file) { if(http://www.php.net/is_object($this->createobjectfromdirfile($file))) { $arr[get_class($this->createobjectfromdirfile($file))] = [ 'class' => $this->createobjectfromdirfile($file), 'methods' => $this->getobjectmethods($this->createobjectfromdirfile($file)) ]; } } return $arr; }
foreach($this->collection as $iterate => $data) { $ob = $this->collection[$iterate]; foreach ($ob['methods'] as $method) { $classmethod = $ob['class']->$method(); if ($classmethod['route'] == http://www.php.net/implode('/', $this->parseurl())) { $view = new RenderRouteView($classmethod['view'], $classmethod['args']); return $view->renderview(); } } }
Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)