Davood
5 سال پیش توسط Davood مطرح شد
15 پاسخ

url فارسی در mvc

سلام
من دوره mvc شما رو خریدم میخوام روت بنویسم به صورت فارسی ولی جواب نمیده ارور میده روت من

$router->add('/news/arak','cityController@index');

این حالت کار میکنه
اما این حالت

$router->add('/news/اراک','cityController@index');

کار نمیکنه چرا؟؟؟؟

@hesammousavi


ثبت پرسش جدید
سیدعلی موسوی
تخصص : سی شارپ و پی اچ پی
@juza66 5 سال پیش مطرح شد
2

اون متن رو بذار تویی wall card بعدش که متن رو گرفتی where کن

Route::get('user/{id}', function ($id) {
    return 'User '.$id;
});

Davood
تخصص : PHP - Laravel
@dfardabasi 5 سال پیش مطرح شد
0

لاراول نیست پروژه
mvc هست


سیدعلی موسوی
تخصص : سی شارپ و پی اچ پی
@juza66 5 سال پیش آپدیت شد
0

پروژه تون هم اگر pure باشه براش باید بنویسی، متغییر جایگیزینش کن و تویی فاکنشت متغییر رو بگیر و استفاده بکن


Davood
تخصص : PHP - Laravel
@dfardabasi 5 سال پیش مطرح شد
Alimotreb
تخصص : کانفیگ سرور و برنامه نویس
@Alimotreb 5 سال پیش مطرح شد
0

سلام
@dfardabasi

یکی از راه هارو که دوستمون اشاره کردند با متغیر کار کنید
شما دارید pure کار میکنید

توی لاراول که همچین مشکلی نیست !
چون مکانیزم روتش خب پیشرفته هست

توی pure شما بایستی پارامتری که میگیرید رو charset براش تعریف شه
unicode اون پارامتر تعیین بشه
به حالت یه استرینگ خالص در بیاد!
تا وب سرور بتونه شناسایی کنه و هندل کنه!


Davood
تخصص : PHP - Laravel
@dfardabasi 5 سال پیش مطرح شد
0

@Alimotreb
میشه یه مثال برام بزنید یا یه کد نمونه بهم معرفی کنید؟


Davood
تخصص : PHP - Laravel
@dfardabasi 5 سال پیش مطرح شد
حسام موسوی
تخصص : طراح و برنامه نویس
@hesammousavi 5 سال پیش مطرح شد
0

بببینید چیزی که دوستان گفتن رو باید رعایت کنید در دوره mvc هم توضیح دادیم که چطور میتونید در url متغییر پاس بدید
اینکه شما بیاد برای تک تک اخبارتون روت مشخص کنید یکار مسخره به حساب میاد و نشدنی
شما اگر روت پویا دارید برای برگشت یک متغییر ثبت میکنید و اطلاعات رو در متد مورد نظر دریافت میکنید.


Davood
تخصص : PHP - Laravel
@dfardabasi 5 سال پیش مطرح شد
0

@hesammousavi
همین کار رو کردم مهندس این رو برات درک بهتر گذاشتم
روتی که تعریف کردم به این شکله

$router->add('/news/{city}','cityController@index');

حالا وقتی داخل این متغیر فارسی یعنی city یه متن فارسی ارسال کنم ارور میده ولی اینگلیسی کار میکنه
هم از دوستان پرسیدم هم سرچ کردم و همه بحث unicode و charset رو گفته بودن ولی خوب نگفتن کجا اضافش کنم
از شما پرسیدم چون بر طبق آموزش شما دارم کار میکنم.


حسام موسوی
تخصص : طراح و برنامه نویس
@hesammousavi 5 سال پیش مطرح شد
0

دقیقا چه اروری میده


Davood
تخصص : PHP - Laravel
@dfardabasi 5 سال پیش آپدیت شد
0

@hesammousavi

Fatal error
Uncaught exception: 'Exception'

Message : 'no route matched.'

Stack trace:

0 C:\xampp\htdocs\afmPdf\public\index.php(13): Core\Router->dispatch('news/\xD8\xA7\xD8\xB1\xD8\xA7\xDA\xA9')
1 {main}
Thrown in 'C:\xampp\htdocs\afmPdf\Core\Router.php' on line 74

اینم route که تو آموزش نوشتیم

<?php namespace Core;

class Router
{
    protected $routes = [];

    protected $params = [] ;

    protected $namespace = 'App\Controllers\\';

    public function add($route , $params )
    {
        $route = preg_replace('/^\//','' , $route);

        $route = preg_replace('/\//' , '\\/' , $route);

        $route = preg_replace('/\{([a-z]+)\}/' , '(?<\1>[a-z0-9-]+)' , $route);

        $route = '/^' . $route . '\/?$/i';

        if(is_string($params)) {
            list($AllParams['controller'] , $AllParams['method']) = explode('@' , $params);
        }

        if(is_array($params)) {
            list($AllParams['controller'] , $AllParams['method']) = explode('@' , $params['uses']);
            unset($params['uses']);
            $AllParams = array_merge($AllParams , $params);

        }

        $this->routes[$route] = $AllParams;
    }

    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['params'][$key] = $match;
                    }
                }
                $this->params = $params;
                return true;
            }
        }
        return false;
    }

    public function dispatch($url)
    {
        $url = $this->removeVariblesOfQueryString($url);
        if($this->match($url)) {
            $controller = $this->params['controller'];
            $controller =  $this->getNameSpace() . $controller;

            if(class_exists($controller)) {
                $controller_object = new $controller();

                $method = $this->params['method'];

                if(is_callable([$controller_object , $method])) {
                        $this->params['params'] = isset($this->params['params']) ? $this->params['params'] : [];
                        echo call_user_func_array([$controller_object , $method] , $this->params['params']);

                } else {
                    throw new \Exception("Method {$method} (in controller {$controller}) not found");
                }
            } else {
                throw new \Exception("Controller class {$controller} not found",404);
            }
        } else {
            throw new \Exception("no route matched.",404);
        }
    }
    public function getRoutes()
    {
        return $this->routes;
    }

    public function getParams()
    {
        return $this->params;
    }

    protected function getNameSpace()
    {
        $namespace = $this->namespace;

        if(array_key_exists('namespace' , $this->params)) {
            $namespace .= $this->params['namespace'] . '\\';
        }

        return $namespace;
    }

    protected function removeVariblesOfQueryString($url)
    {
        if($url != '') {
            $parts = explode("&" , $url , 2);
            if(strpos($parts[0] , '=') === false) {
                $url = $parts[0];
            } else {
                $url = '';
            }
            return $url;
        }
    }

}

کجاشو باید تغییر بدم؟


Davood
تخصص : PHP - Laravel
@dfardabasi 5 سال پیش آپدیت شد
0

@Alimotreb
@ali.bayat

ببخشید میشه بهم بگید کجای این کدهای فایل route رو باید تغییر بدم که روت های فارسی رو هم جواب بده؟؟؟؟

<?php namespace Core;

class Router
{
    protected $routes = [];

    protected $params = [] ;

    protected $namespace = 'App\Controllers\\';

    public function add($route , $params )
    {
        $route = preg_replace('/^\//','' , $route);

        $route = preg_replace('/\//' , '\\/' , $route);

        $route = preg_replace('/\{([a-z]+)\}/' , '(?<\1>[a-z0-9-]+)' , $route);

        $route = '/^' . $route . '\/?$/i';

        if(is_string($params)) {
            list($AllParams['controller'] , $AllParams['method']) = explode('@' , $params);
        }

        if(is_array($params)) {
            list($AllParams['controller'] , $AllParams['method']) = explode('@' , $params['uses']);
            unset($params['uses']);
            $AllParams = array_merge($AllParams , $params);

        }

        $this->routes[$route] = $AllParams;
    }

    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['params'][$key] = $match;
                    }
                }
                $this->params = $params;
                return true;
            }
        }
        return false;
    }

    public function dispatch($url)
    {
        $url = $this->removeVariblesOfQueryString($url);
        if($this->match($url)) {
            $controller = $this->params['controller'];
            $controller =  $this->getNameSpace() . $controller;

            if(class_exists($controller)) {
                $controller_object = new $controller();

                $method = $this->params['method'];

                if(is_callable([$controller_object , $method])) {
                        $this->params['params'] = isset($this->params['params']) ? $this->params['params'] : [];
                        echo call_user_func_array([$controller_object , $method] , $this->params['params']);

                } else {
                    throw new \Exception("Method {$method} (in controller {$controller}) not found");
                }
            } else {
                throw new \Exception("Controller class {$controller} not found",404);
            }
        } else {
            throw new \Exception("no route matched.",404);
        }
    }
    public function getRoutes()
    {
        return $this->routes;
    }

    public function getParams()
    {
        return $this->params;
    }

    protected function getNameSpace()
    {
        $namespace = $this->namespace;

        if(array_key_exists('namespace' , $this->params)) {
            $namespace .= $this->params['namespace'] . '\\';
        }

        return $namespace;
    }

    protected function removeVariblesOfQueryString($url)
    {
        if($url != '') {
            $parts = explode("&" , $url , 2);
            if(strpos($parts[0] , '=') === false) {
                $url = $parts[0];
            } else {
                $url = '';
            }
            return $url;
        }
    }

}

اینم ارورمه

Fatal error
Uncaught exception: 'Exception'

Message : 'no route matched.'

Stack trace:

0 C:\xampp\htdocs\afmPdf\public\index.php(13): Core\Router->dispatch('news/\xD8\xA7\xD8\xB1\xD8\xA7\xDA\xA9')
1 {main}
Thrown in 'C:\xampp\htdocs\afmPdf\Core\Router.php' on line 74

حسام موسوی
تخصص : طراح و برنامه نویس
@hesammousavi 5 سال پیش مطرح شد
2

به عنوان کدنویس از ارور باید شروع به دیباگ کنید !
الان برای مثال این خط داره ارور رو میده

throw new \Exception("no route matched.",404);

خوب مشخصه if اون صحیح بر نمیگردونه یعنی :

$this->match($url)

و داخل این چه خبره ؟
و احتمالا در خط زیر مشکل داره

preg_match($route , $url , $matches)

من به سیستم دسترسی ندارم چیزی که الان میگم رو تست کنم ولی مورد زیر رو جایگزین خط مربوطه در add کنید
این رو

  $route = '/^' . $route . '\/?$/i';

به این تبدیل کنید

        $route = '/^' . $route . '\/?$/iu';

یا

       $route = '/^' . $route . '\/?$/u';

و یه نکته، اگر به مهارتی در php نرسیدید که خودتون debug کنید یا درک کنید چی دارید مینویسید خواها دست به نوشتن یک فریمورک با mvc نزنید چون اینکار احتمالا تنها باعث ایجاد باگ در پروژهای شما میشه و در اینده مشکلات فراوانی براتون پیش میاره . پیشنهاد میکنم اول از فریمورک های مثل لاراول استفاده کنید درکشون کنید در توسعه اش کمک کنید .
روی مهارت مهندسی نرم افزار کار کنید
و بعد اقدام به این کار کنید . این خیلی مهمه . امیدوارم به دیدید توصیه مهم بهش نگاه کنید .


Davood
تخصص : PHP - Laravel
@dfardabasi 5 سال پیش مطرح شد
0

خیلی ممنون از توصیه خوبتون حتما بهش عمل میکنم

@hesammousavi

این دو تا تغییری که گفتید تست کردم کار نکرد هنوزم ارور میده

البته من دیشب یه کاری انجام دادم که به صورت نصفه نیمه عمل کرد
آمدم تو preg_replace فارسی هم نوشتم که پشتیبانی کنه
اول به این صورت نوشتم جواب نداد

preg_replace('/\{([a-z]+)\}/' , '(?<\1>[a-z0-9-ا-ی]+)' , $route);

و بعد به این صورت نوشتم جواب داد یعنی نصفه و نیمه

preg_replace('/\{([a-z]+)\}/' , '(?<\1>[a-z0-9-ا-آ-ب-پ-ت-ث-ج-چ-ه-خ-د-ذ-ر-ز-ژ-س-ش-ص-ض-ط-ظ-ع-غ-ف-ق-ک-گ-ل-م-ن-و-ه-ی]+)' , $route);

منظورم اینه من 12 تا شهرستان دارم که میخوام با url فارسی باز بشه این کد 3 تا از شهرها رو باز نمیکنه

لیست شهرهام : اراک ساوه شازند تفرش خمین محلات دلیجان کمیجان خنداب فراهان آشتیان زرندیه

خمین محلات کمیجان باز نیمشن بقیه مشکلی ندارن


حسام موسوی
تخصص : طراح و برنامه نویس
@hesammousavi 5 سال پیش مطرح شد
0

خوب بلاخره به سیستم دسترسی پیدا کردم و تست کردم
کل پروژه باگی داشت که حل کردم اینکه سه کلمه باز نمیشن بخاطر ارور apache بود. حالا اینکارهای که میگم انجام بدید حل میشه اول کد زیر رو در htaccess جایگزین کنید

# Remove the question mark from the request but maintain the query string
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ index.php [L]

و کد زیر رو در فایل index.php

<?php
require '../bootstrap/autoload.php';

error_reporting(E_ALL);
set_error_handler('Core\Error::errorHandler');
set_exception_handler('Core\Error::exceptionHandler');

$router = require "../App/Router.php";
$router->dispatch(urldecode(substr($_SERVER["REQUEST_URI"],1)));

و در نهایت یک تغییر در متد پایین و حل میشه

    public function add($route , $params )
    {
        $route = preg_replace('/^\//','' , $route);

        $route = preg_replace('/\//' , '\\/' , $route);

        $route = preg_replace('/\{([a-z]+)\}/' , '(?<\1>[a-zA-Z0-9 -پچجحخهعغفقثصضشسیبلاتنمکگوئدذرزطظژؤإأءًٌٍَُِّ]+)' , $route);

        $route = '/^' . $route . '\/?$/i';

        if(is_string($params)) {
            list($AllParams['controller'] , $AllParams['method']) = explode('@' , $params);
        }

        if(is_array($params)) {
            list($AllParams['controller'] , $AllParams['method']) = explode('@' , $params['uses']);
            unset($params['uses']);
            $AllParams = array_merge($AllParams , $params);

        }

        $this->routes[$route] = $AllParams;
    }

در صورت انجام اینها مشکلتون حل میشه


برای ارسال پاسخ لازم است وارد شده یا ثبت‌نام کنید

ورود یا ثبت‌نام