How should I do Exception on Laravel5 Resource Controller? - php

I know Laravel5 Resource method will work like this.
TestControler#index /aa
TestControler#edit /aa/{aa}/edit
..
It's good to work if integer have been inserted.
/aa/1/edit -> work
But it will broken if string is coming.
/aa/aa/edit -> SQLSTATE[22P02]: Invalid text representation ..
So I wanna ask you the question is how should I allow request url thats integer only?
where should I write, route.php or Controller?
and how to abort 404 if string is coming.
any idea?

Expanding on my comment:
When working with Laravel's router, for any parameter you add to a URI definition (such as {id}), you can add a regex constraint. The constraint will take the variable value and test to see if the regex matches the value. If the regex fails, then the route will not be selected.
You do this using the where() method on the route and passing an associative array where the keys correspond to the variables in the URI, and the values are regexes to match. You can add constraints to as many variables in a route's URI as you like.
For example, if you wanted to constrain the id value in your URI to just numbers, you could do something like this:
Route::get("users/{id}", "Users#getUser")->where(["id" => "[0-9]+"]);
The documentation for this feature states:
You may constrain the format of your route parameters using the where method on a route instance. The where method accepts the name of the parameter and a regular expression defining how the parameter should be constrained
See more examples in the documentation available here: https://laravel.com/docs/5.2/routing#parameters-regular-expression-constraints

Thanks to reply, Finally It works great.
But I wanna add this to my post.
Where method will work when I write 'standard' routing like this.
Route::get('/aa/{aa}/edit','TestsController#delete')->name('aa.edit')->where('aa','[0-9]+'); // works great!
But that's not work if I write 'RESTful' routing like this.
Route::resource('/aa', 'TestsController')->where('aa','[0-9]+'); // not work!
So I wrote this to app/route.php, It works very fine.
Route::pattern('aa', '\d+');
Route::get('/aa/{aa}/delete','TestsController#delete')->name('aa.delete')->where('aa','[0-9]+');
Route::resource('/aa', 'TestsController')->where('aa','[0-9]+');

Related

Laravel: how to limit some route parameter to specific values?

Is that possible to make route that accept string parameter only for specific string? Example :
Route::get('{user_tipe}/event', 'admin\EventC#index');
That the route, I want to make the user_tipe param is only allow to two string like admin and author. Is that possible?
You can do that using regular expression constraits on your route:
Route::get('{user_tipe}/event', 'admin\EventC#index')->where('user_tipe', 'admin|author');
admin|author is a simple regular expression that will match either the string admin or author
UPDATE
Here you can find how to use the route param constraints when using Route::group

PHP: Url as parameter

I'm building a small restful api and I'm asking if it's possible to seperate the url to php file and the end of the url.
E.g. www.mydomain.com/api/parameter/1/2/
In this case the php file is adressed with www.mydomain.com/api/ or www.mydomain.com/api/index.php and parameter/1/2/ is the parameter.
I want a CRUD interface so that GET without parameter gets a list of all data. To achieve this I need to check if a parameter is attached and to extract the parameter.
Other example
www.mydomain.com/topics/ => gets all topics
www.mydomain.com/topics/1/posts/ => gets all posts of topic 1,
www.mydomain.com/topics/1/posts/2/ => gets post 2 of topic 1
My question is: Is it possible and how?
You would probably have to read the request URI from the end of the URL using $_SERVER['request_uri']. This would return /api/parameter/1/2. You could then substring it if the length is reliable, or use a regex with preg_match to get just the parameter section. e.g.
preg_match("parameter\/.*", $_SERVER['request_uri'], $matches)
would return either the string parameter/1/2 in the $matches variable, or false if no match was found
But yeah like others are saying, you're probably better using GET parameters if you can, and just do a check using isset() to see if there are any parameters.

Route parameter patterns on routes with similar parameters

I have a few routes that takes a couple of UUIDs as parameters:
Route::get('/foo/{uuid1}/{uuid2}', 'Controller#action');
I want to be able to verify that those parameters are the correct format before passing control off to the action:
Route::pattern('uuid1', '^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$');
This works fine. However, I really don't want to repeat that pattern so many times (in the real case I have it repeated 8 times for 8 different UUID route parameters).
I can't do this:
Route::get('/foo/{uuid}/{uuid}', 'Controller#action');
Because that produces an error:
Route pattern "/foo/{uuid}/{uuid}" cannot reference variable name "uuid" more than once.
I can lump them all into a single function call since I discovered Route::patterns:
Route::patterns([
'uuid1' => '^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$',
'uuid2' => '^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$',
]);
But that is still repetitious. Is there a way I can bind multiple pattern keys to a single regular expression?
Ideally I'd like to find a way that avoids something like this:
$pattern = 'uuid regex';
Route::patterns([
'uuid1' => $pattern,
'uuid2' => $pattern,
]);
There's no built in way to handle this, and I actually think the solution you found is pretty nice. Maybe a bit more elegant would be this:
Route::patterns(array_fill_keys(['uuid1', 'uuid2'], '/uuid regex/'));

How to get query string values in YII without PATH format?

I am having following url,
www.example.com/index.php?r=recommend/create&id=184?
title=Ruins%20of%20Mahabalipuram
&url=http://localhost/index.php/mediadetail/index/184
I need to get title and url which are query string parameters.
Has anyone worked on getting values in query string in Yii?
There is also the getParam() method in CHttpRequest.
Yii::app()->request->getParam('title')
I've found it a valuable shortcut, since it checks both $_POST and $_GET and gives priority to $_GET, so you can use it to override post variables in the address URL. It also performs null checks and you can provide a default value in the second parameter.
The drawbacks are that you can't use it for arrays and maybe it's a little bit verbose (compared to $_GET['title']).
Look the function parse_str, it would worked and if not, look parse_url but it's not necessary for what you want to do.
They'll automatically be available in your action as $_GET variables. Yii handles parsing them for you as part of the CHttpRequest object

Why does Symfony escape & characters when using url_for()?

With this Symfony page, I am passing $_GET parameters in the URI like this:
http://www.mysite.com/article?page=4&sort=1
Once in my layout, there are certain links in the page that need to have the same query string in them.
Anyways, using Symfony's url_for() command I'm making URLs like so:
$url = url_for('article/index?.http_build_query($_GET));
That way it makes a new url using the $_GET variables. For some of the links I'm changing the $_GET values ahead of time, like $_GET['sort']=0; before generating the url. That's why I'm using this method.
Anyways, when I look at the generated URL, it now looks like this:
http://www.mysite.com/article?page=4&amp%3Bsort=1
The &amp%3B is the encoded form of & which is just an & character.
So the problem is that when I check for my $_GET parameters in my controller now, there is no longer a sort parameter that is passed. It's now called &amp%3Bsort... It's causing all sorts of issues.
Two questions:
How do I avoid this problem? Can I decode the $_GET parameter key values in my controller or something?
Why is symfony encoding a & character in the first place? It's a perfectly acceptable URI character. Heck, even the encoded value, &amp%3B contains a & !!!
I believe, it is because of output escaping is ON in your application. As a result, $_GET array is wrapped inside sfOutputEscaperArrayDecorator class. You can get a raw value using this: $_GET->getRawValue().
$url = url_for('article/index?.http_build_query($_GET->getRawValue()))
Or you can decode the result query using sfOutputEscaper::unescape
$url = url_for('article/index?.sfOutputEscaper::unescape(http_build_query($_GET)));
Hope this will be useful.
Best if you use Symfony's own method for getting the request parameters. For example, in templates, use:
$sf_request->getParameter('some_param');
If you must use $_GET, maybe try:
((( $sf_data->getRaw('_GET') )))
... to get past the output escaping. Not totally sure if that'll work as is.

Categories