۵ AmirAliDev
مشکل در روتر
جامعه پی اچ پی ایجاد شده در ۲۲ مهر ۱۴۰۱

سلام خسته نباشید من تو پوشه روتز فقط میتونم یک روتر صدا بزنم و هر روت دیگه ای که ایجاد میکنم با مشکل مواجه میشم و وقتی بالای روتی که a/ هست روت تعریف میکنم با ارور مواجه میشم

Warning: Undefined array key "methods" in C:\\Users\\AmirAli\\Desktop\\MicroFAV\\App\\Core\\Routing\\Router.php on line 24
Fatal error: Uncaught TypeError: in_array(): Argument #2 ($haystack) must be of type array, null given in C:\\Users\\AmirAli\\Desktop\\MicroFAV\\App\\Core\\Routing\\Router.php:24 Stack trace: #0 C:\\Users\\AmirAli\\Desktop\\MicroFAV\\App\\Core\\Routing\\Router.php(24): in_array('get', NULL) #1 C:\\Users\\AmirAli\\Desktop\\MicroFAV\\App\\Core\\Routing\\Router.php(16): app\\Core\\Routing\\Router->findRoute(Object(app\\Core\\Request)) #2 C:\\Users\\AmirAli\\Desktop\\MicroFAV\\index.php(6): app\\Core\\Routing\\Router->__construct() #3 {main} thrown in C:\\Users\\AmirAli\\Desktop\\MicroFAV\\App\\Core\\Routing\\Router.php on line 24

فقط یک روت من اجرا میشه اونم به شرطی که بالاش روتی نباشه مثل a/

وقتی تعریف نمیکنم روت a/ کار میکنه و وقتی پایین a/ روت تعریف میکنم ارور نمیده و کار هم نمیکنه نمیدونم مشکل از کجاست ممنون میشم راهنمایی کنید!

https://github.com/amiralidev01/MicroFAV-Framework

سلام امیرعلی جان

من مشکلت رو متوجه نشدم، میتونی یکم برام بیشتر توضیح بدی؟

محمد گازری ۲۲ مهر ۱۴۰۱، ۱۷:۴۰

استاد وقتی تو پوشه route و فایل web.php روت تعریف میکنم عملا یک روت بیشتر کار نمیکنه و بقیه رو نال بر میگردونه

AmirAliDev ۲۳ مهر ۱۴۰۱، ۱۴:۲۴

توی فایل route.php مشکل داشتی

باید متد هایی به جز add در فایل Route رو بیای و درست بنویسی

مثلا الان در متد add اومدی نوشتی که

public static function add($methods, $uri, $action = null)
{
    $methods = is_array($methods) ? $methods : [$methods];
    self::$routes[] = ['methods' => $methods, 'uri' => $uri, 'action' => $action];
}

خب اگر به کد بالا دقت کنی در اینجا اومدی و متد‌ها رو چه آرایه باشن چه نباشن داخل آرایه قرار دادی

بعد خروجیش میشه این

Array
(
    [methods] => Array
        (
            [0] => post
            [1] => get
        )
    [uri] => /a
    [action] => Closure Object
        (
        )
)

اما اومدی کد متد get رو به شکل زیر نوشتی

public static function get($uri, $action = null): void
{
    self::$routes[] = ['get', 'uri' => $uri, 'action' => $action];
}

که خروجیش میشه کد زیر

Array
(
    [0] => get
    [uri] => /hello
    [action] => Closure Object
        (
        )
)

دقت کردی به تفاوت کلید methods در خروجی آرایه ها؟

حالا چرا برنامت ارور میده؟

در خط ۲۴ فایل Router.php اومدی و به عنوان کلید آرایه صدا زدی قسمت methods رو! (قسمت route['methods'])

if (in_array($request->method(), $route['methods']) and $request->uri() == $route['uri']) {
  return $route;
}

حالا ۲ تا راه حل داری

۱. بیای و همه متدهات رو اینجوری بنویسی

public static function get($uri, $action = null): void
{
    self::add('get', $uri, $action);
}

کد بالا کار میکنه اما اگر دقت کنی برای همه کدها تکرار داریم و این اصول clean code رو نقض میکنه

راه حل ۲

۲. بیای و به این شکل و خیلی تمیز کلاس Route.php رو بنویسی

class Route
	{
	    private static $routes = [];
	    public static function add(array|string $method, string $uri, $action = null, array $middleware = [])
	    {
	        $methods = is_array($method) ? $method : [$method];
	        self::$routes[] = [
	            'methods' => $methods,
	            'uri' => $uri,
	            'action' => $action,
	            'middleware' => $middleware
	        ];
	    }
	    public static function __callStatic($name, $arguments)
	    {
	        $verbs = ['get', 'post', 'put', 'patch', 'delete', 'options'];
	        if (!in_array($name, $verbs))
	            throw new \\Exception('Request method not support!');
	        $uri = $arguments[0];
	        $action = $arguments[1] ?? null;
	        $middleware = $arguments[2] ?? [];
	        self::add($name, $uri, $action, $middleware);
	    }
	    public static function routes()
	    {
	        return self::$routes;
	    }
	}
محمد گازری ۲۴ مهر ۱۴۰۱، ۰۵:۳۲

استاد مشکلم حل نشد

AmirAliDev ۲۴ مهر ۱۴۰۱، ۱۰:۳۳

اون راه حلی که بهت گفتم برای مشکل قبلیت بود که خطای خط ۲۴ داشتی و برنامه کار نمیکرد کلا!

این مشکلت هم علتش اینه return null رو توی foreach نوشتی!

کد درست به شکل زیر

public function findRoute(Request $request)
{
    foreach ($this->routes as $route) {
        if (in_array($request->method(), $route['methods']) and $request->uri() == $route['uri']) {
            return $route;
        }
    }
    return null;
}
بهترین پاسخ
محمد گازری ۲۴ مهر ۱۴۰۱، ۱۰:۴۹