سلام
من دوره mvc شما رو خریدم میخوام روت بنویسم به صورت فارسی ولی جواب نمیده ارور میده روت من
$router->add('/news/arak','cityController@index');
این حالت کار میکنه
اما این حالت
$router->add('/news/اراک','cityController@index');
کار نمیکنه چرا؟؟؟؟
اون متن رو بذار تویی wall card بعدش که متن رو گرفتی where کن
Route::get('user/{id}', function ($id) {
return 'User '.$id;
});
پروژه تون هم اگر pure باشه براش باید بنویسی، متغییر جایگیزینش کن و تویی فاکنشت متغییر رو بگیر و استفاده بکن
سلام
@dfardabasi
یکی از راه هارو که دوستمون اشاره کردند با متغیر کار کنید
شما دارید pure کار میکنید
توی لاراول که همچین مشکلی نیست !
چون مکانیزم روتش خب پیشرفته هست
توی pure شما بایستی پارامتری که میگیرید رو charset براش تعریف شه
unicode اون پارامتر تعیین بشه
به حالت یه استرینگ خالص در بیاد!
تا وب سرور بتونه شناسایی کنه و هندل کنه!
بببینید چیزی که دوستان گفتن رو باید رعایت کنید در دوره mvc هم توضیح دادیم که چطور میتونید در url متغییر پاس بدید
اینکه شما بیاد برای تک تک اخبارتون روت مشخص کنید یکار مسخره به حساب میاد و نشدنی
شما اگر روت پویا دارید برای برگشت یک متغییر ثبت میکنید و اطلاعات رو در متد مورد نظر دریافت میکنید.
@hesammousavi
همین کار رو کردم مهندس این رو برات درک بهتر گذاشتم
روتی که تعریف کردم به این شکله
$router->add('/news/{city}','cityController@index');
حالا وقتی داخل این متغیر فارسی یعنی city یه متن فارسی ارسال کنم ارور میده ولی اینگلیسی کار میکنه
هم از دوستان پرسیدم هم سرچ کردم و همه بحث unicode و charset رو گفته بودن ولی خوب نگفتن کجا اضافش کنم
از شما پرسیدم چون بر طبق آموزش شما دارم کار میکنم.
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;
}
}
}
کجاشو باید تغییر بدم؟
ببخشید میشه بهم بگید کجای این کدهای فایل 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
به عنوان کدنویس از ارور باید شروع به دیباگ کنید !
الان برای مثال این خط داره ارور رو میده
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 نزنید چون اینکار احتمالا تنها باعث ایجاد باگ در پروژهای شما میشه و در اینده مشکلات فراوانی براتون پیش میاره . پیشنهاد میکنم اول از فریمورک های مثل لاراول استفاده کنید درکشون کنید در توسعه اش کمک کنید .
روی مهارت مهندسی نرم افزار کار کنید
و بعد اقدام به این کار کنید . این خیلی مهمه . امیدوارم به دیدید توصیه مهم بهش نگاه کنید .
خیلی ممنون از توصیه خوبتون حتما بهش عمل میکنم
این دو تا تغییری که گفتید تست کردم کار نکرد هنوزم ارور میده
البته من دیشب یه کاری انجام دادم که به صورت نصفه نیمه عمل کرد
آمدم تو preg_replace فارسی هم نوشتم که پشتیبانی کنه
اول به این صورت نوشتم جواب نداد
preg_replace('/\{([a-z]+)\}/' , '(?<\1>[a-z0-9-ا-ی]+)' , $route);
و بعد به این صورت نوشتم جواب داد یعنی نصفه و نیمه
preg_replace('/\{([a-z]+)\}/' , '(?<\1>[a-z0-9-ا-آ-ب-پ-ت-ث-ج-چ-ه-خ-د-ذ-ر-ز-ژ-س-ش-ص-ض-ط-ظ-ع-غ-ف-ق-ک-گ-ل-م-ن-و-ه-ی]+)' , $route);
منظورم اینه من 12 تا شهرستان دارم که میخوام با url فارسی باز بشه این کد 3 تا از شهرها رو باز نمیکنه
لیست شهرهام : اراک ساوه شازند تفرش خمین محلات دلیجان کمیجان خنداب فراهان آشتیان زرندیه
خمین محلات کمیجان باز نیمشن بقیه مشکلی ندارن
خوب بلاخره به سیستم دسترسی پیدا کردم و تست کردم
کل پروژه باگی داشت که حل کردم اینکه سه کلمه باز نمیشن بخاطر ارور 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;
}
در صورت انجام اینها مشکلتون حل میشه
آیا مایل به ارسال نوتیفیکیشن و اخبار از طرف راکت هستید ؟