Get URL segment in Laravel 5 - php

For accessing previous URL in laravel. I am using this code in my controller.
$current_url = Request::url();
$back_url = redirect()->back()->getTargetUrl();
if ($current_url != $back_url) {
Session::put('previous_url', redirect()->back()->getTargetUrl());
}
This method helps maintainging previous url even when server side validation fails.
In my blade I access previous url like this {{ Session::get('previous_url') }}.
I need to find the second segment of my previous url.
Thanks

You can do it this way:
request()->segment(2);
request() is a helper function that returns Illuminate\Http\Request, but you can also use the facade Request or inject the class as a dependency in your method.
EDIT
with the redirect back: redirect()->back()->getRequest()->segment(2);

Under the hood, Laravel is doing these two things to get the segments of a url (from within the Request class):
public function segment($index, $default = null)
{
return Arr::get($this->segments(), $index - 1, $default);
}
public function segments()
{
$segments = explode('/', $this->path());
return array_values(array_filter($segments, function ($v) {
return $v != '';
}));
}
You could do something similar in a helper function:
public function segment($url, $index, $default)
{
return Arr::get($this->segments($url), $index - 1, $default);
}
public function segments($url)
{
$segments = explode('/', $url);
return array_values(array_filter($segments, function ($v) {
return $v != '';
}));
}

Related

Removing function name URL in Codeigniter CMS

when data pass in controller that time the data and function name pass into URL
localhost/project/course/Web-Development
the above example course is function name of controller
but remove it and pass this URL
localhost/project/Web-Development
using remap function we can solve this problem
code in controller
public function _remap($method, $params = array())
{
if ($method == 'autocomplete') {
return call_user_func_array(array($this, $method), $params);
} else {
$methodcall = $this->M_tl_admin->Validate_Web($method);
if ($methodcall == 'course') //***course is your function name***
return call_user_func_array(array($this, $methodcall), array($method));
}
}
code in model
public function Validate_Web($alias)
{
$res = $this->db->get_where('category', array('ctg_url' => $alias))->result_array();//category is table name and ctg_url is data pass in URL(Web-Development)
if(count($res)>0)
return 'course';
}
You can use route features to hide function name.
https://www.codeigniter.com/user_guide/general/routing.html
$route['product/:any'] = 'project/product_look

Is there a way to ignore the subdomain value in subdomain routing

According to Lavarel documentation, if I use subdomain routing for multiple subdomains, I have to pass the subdomain as the first argument of callbacks functions and controllers methods:
Route::domain('{sub}.example.org')->group(function () {
Route::get('a', function ($sub) { /* ... */ });
Route::get('b', function ($sub) { /* ... */ });
Route::get('c/{c}', function ($sub, $c) { /* ... */ });
Route::get('d/{d}', function ($sub, $d) { /* ... */ });
});
In other words, I have to carry the $sub variable everywhere. Assuming I don't care about its value, can I avoid this and just do something like this(this does not work for multiple argument):
Route::domain('{sub}.example.org')->group(function () {
Route::get('a', function () { /* ... */ });
Route::get('b', function () { /* ... */ });
Route::get('c/{c}', function ($c) { /* ... */ });
Route::get('d/{d}', function ($d) { /* ... */ });
});
If I do this, $c and $d will be the value of the subdomain.
Assuming I don't care about the subdomain value and I have many routes, is there a way to ignore it?
We had a similar thing with a dynamical prefix. Our solution was:
First we unset the parameter if it existed in the "App/Http/Controllers/Controller.php", which is the class your controllers most likely extend.
public function callAction($method, $parameters)
{
if (isset($parameters['clientident'])) {
unset($parameters['clientident']);
}
return parent::callAction($method, $parameters);
}
This will unset the parameter for every function call in every controller and should do away with your problem.
But because we needed it in our route() function, we created a "App/Http/helpers.php" file for
function route($name, $parameters = [], $absolute = true)
{
if (!isset($parameters['clientident'])) {
// If the given value is not an array, wrap it in one.
$parameters = Arr::wrap($parameters);
if (Auth::check()) {
$temp = ['clientident' => Auth::user()->getClientIdent()];
}
else if (request()->clientident) {
$temp = ['clientident' => request()->clientident];
}
else {
$temp = ['clientident' => 'general'];
}
$parameters = array_merge($parameters, $temp);
}
return app('url')->route($name, $parameters, $absolute);
}
and added the new helpers file in the "bootstrap/autoload.php"
require __DIR__.'/../app/Http/helpers.php';
require __DIR__.'/../vendor/autoload.php'; << this line was already here
This works because Taylor wrote an check in front of every helper function if it is already set, so it's pretty easy to override them
if (! function_exists('route')) {
function route($name, $parameters = [], $absolute = true)
{
return app('url')->route($name, $parameters, $absolute);
}
}
is the code in the helpers.php in the Illuminate/Foundation directory.
I guess the route function has to be handled a little bit different in your case. You should be able to get the subdomain with domain helper functions and add it there as parameter back again, which is most likely much easier than our if elseif else case above.

In symfony, how can i get Global methods and variables in any Controller?

The scene is, the client (All request like Ajax in my site) will request a json string like that {"token":"mytoken"}.PHP receive it by $request->getContent() and json_decode it. I store it in a variable named $data so i can get it in any Controller.
I also create a method to get value by key, code like that
public function input($key, $default = '', $func = '')
{
$ret = '';
if (isset($this->data[$key])) {
$ret = $this->data[$key];
} else {
return $default;
}
if (is_string($func)) {
if (in_array($func, ['int', 'string', 'array'])) {
settype($ret, $func);
return $ret;
}
if ($func)
$ret = call_user_func($func, $ret);
} elseif (is_array($func)) {
if ($func)
$ret = call_user_func_array($func, [$ret]);
}
if (!$ret)
return $default;
return $ret;
}
Although i can reg it to server, but i use it like that $this->get('input')->input($mykey);, this will appear in any controller. Is this a proposed solution?
The question just my title, HOW? Save me .
Consider adding a request event listener that parses the JSON and sets the resulting data in the request object. Example implementation:
<?php
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
class ParseJsonRequestListener
{
public function onKernelRequest(GetResponseEvent $event)
{
$request = $event->getRequest();
// only parse the content body if the content type is JSON
if (preg_match('/\bjson\b/', $request->getContentType())) {
$parameters = json_decode($request->getContent(), true);
if ($parameters) {
$request->request->replace($parameters);
}
}
}
}
Register the listener, for example in app/config/services.yml:
parse_json_request_listener:
class: ParseJsonRequestListener
tags:
- { name: kernel.event_listener, event: kernel.request }
Now in any controller that receives a JSON request, you can get the parsed JSON data from the request, for example:
<?php
$token = $request->request->get('token');
If a method is in controller, then you can add $request object to params:
use Symfony\Component\HttpFoundation\Request;
//...
public function input(Request $request, $key, $default = '', $func = '')
//...
Request object has all global vars. More info: http://symfony.com/doc/current/introduction/http_fundamentals.html#symfony-request-object

How I can grab all public function methods in a controller?

I use __remap() function to avoid any undefine method and make it redirect to index() function.
function __remap($method)
{
$array = {"method1","method2"};
in_array($method,$array) ? $this->$method() : $this->index();
}
That function will check if other than method1 and method2.. it will redirect to index function.
Now, how I can automatically grab all public function methods in that controller instead of manually put on $array variable?
You need to test if method exists and is public. So you need use reflection and method exists. Something like this:
function __remap($method)
{
if(method_exists($this, $method)){
$reflection = new ReflectionMethod($this, $method);
if($reflection->isPublic()){
return $this->{$method}();
}
}
return $this->index();
}
Or you can use get_class_methods() for create your array of methods
OK, I was bored:
$r = new ReflectionClass(__CLASS__);
$methods = array_map(function($v) {
return $v->name;
},
$r->getMethods(ReflectionMethod::IS_PUBLIC));
I've modified the codes and become like this.
function _remap($method)
{
$controllers = new ReflectionClass(__CLASS__);
$obj_method_existed = array_map(function($method_existed)
{
return $method_existed;
},
$controllers->getMethods(ReflectionMethod::IS_PUBLIC));
$arr_method = array();
//The following FOREACH I think was not good practice.
foreach($obj_method_existed as $method_existed):
$arr_method[] = $method_existed->name;
endforeach;
in_array($method, $arr_method) ? $this->$method() : $this->index();
}
Any enhancement instead of using foreach?

use of class:any() in PHP, is ANY a reserved method?

I'm trying to implement Simple MVC Framework http://simplemvcframework.com/ and am going through the code line by line in the index.php file (https://github.com/simple-mvc-framework/v2/blob/master/index.php) and I've come across the following 2 lines..
//define routes
Router::any('', '\controllers\welcome#index');
Router::any('/subpage', '\controllers\welcome#subpage');
I understand :: is a scope resolution operator, and would think that Router::any() would be referencing a static method called any() in the Router class... however no such method exists... https://github.com/simple-mvc-framework/v2/blob/master/app/core/router.php. Though all other static method calls mentioned in the index.php file DO exist.
I thought maybe this was some sort of reserved name of a PHP function, but of course as you could imagine, searching for "PHP Any function" or similar searches in google doesn't come back with too many helpful results. My other thought is maybe this is just a implementation of static calls that I'm not familiar with?
I know this is a very specific question, but I'm trying to make sure I understand as much as possible with this framework and PHP in general before going too much futher.
Here is how it works.
It utilizes __callStatic magic method in PHP.
When a static call is made using Class/Object, and if the magic method is defined in the class, and if the called static function doesn't exist then this method is invoked.
If we dig deeper into the code,
public static function __callstatic($method, $params){
$uri = dirname($_SERVER['PHP_SELF']).'/'.$params[0];
$callback = $params[1];
array_push(self::$routes, $uri);
array_push(self::$methods, strtoupper($method));
array_push(self::$callbacks, $callback);
}
The method parameter which is any in our case is store as uppercase (ANY) with a callback.
When a request is made, dispatch function is called.
public static function dispatch(){
$uri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
$method = $_SERVER['REQUEST_METHOD'];
$searches = array_keys(static::$patterns);
$replaces = array_values(static::$patterns);
self::$routes = str_replace('//','/',self::$routes);
$found_route = false;
// parse query parameters
{
$query = '';
$q_arr = array();
if(strpos($uri, '&') > 0) {
$query = substr($uri, strpos($uri, '&') + 1);
$uri = substr($uri, 0, strpos($uri, '&'));
$q_arr = explode('&', $query);
foreach($q_arr as $q) {
$qobj = explode('=', $q);
$q_arr[] = array($qobj[0] => $qobj[1]);
if(!isset($_GET[$qobj[0]]))
{
$_GET[$qobj[0]] = $qobj[1];
}
}
}
}
// check if route is defined without regex
if (in_array($uri, self::$routes)) {
$route_pos = array_keys(self::$routes, $uri);
// foreach route position
foreach ($route_pos as $route) {
if (self::$methods[$route] == $method || self::$methods[$route] == 'ANY') {
$found_route = true;
//if route is not an object
if(!is_object(self::$callbacks[$route])){
//call object controller and method
self::invokeObject(self::$callbacks[$route]);
if (self::$halts) return;
} else {
//call closure
call_user_func(self::$callbacks[$route]);
if (self::$halts) return;
}
}
}
// end foreach
} else {
// check if defined with regex
$pos = 0;
// foreach routes
foreach (self::$routes as $route) {
$route = str_replace('//','/',$route);
if (strpos($route, ':') !== false) {
$route = str_replace($searches, $replaces, $route);
}
if (preg_match('#^' . $route . '$#', $uri, $matched)) {
if (self::$methods[$pos] == $method || self::$methods[$pos] == 'ANY') {
$found_route = true;
//remove $matched[0] as [1] is the first parameter.
array_shift($matched);
if(!is_object(self::$callbacks[$pos])){
//call object controller and method
self::invokeObject(self::$callbacks[$pos],$matched);
if (self::$halts) return;
} else {
//call closure
call_user_func_array(self::$callbacks[$pos], $matched);
if (self::$halts) return;
}
}
}
$pos++;
}
// end foreach
}
if (self::$fallback) {
//call the auto dispatch method
$found_route = self::autoDispatch();
}
// run the error callback if the route was not found
if (!$found_route) {
if (!self::$error_callback) {
self::$error_callback = function() {
header("{$_SERVER['SERVER_PROTOCOL']} 404 Not Found");
echo '404';
};
}
if(!is_object(self::$error_callback)){
//call object controller and method
self::invokeObject(self::$error_callback,null,'No routes found.');
if (self::$halts) return;
} else {
call_user_func(self::$error_callback);
if (self::$halts) return;
}
}
}
}
If you look deeply into the dispatch function, you will clearly see that, there are several lines containing:
if (self::$methods[$route] == $method || self::$methods[$route] == 'ANY')
This helps routing the request to defined callbacks based on the methods supplied including ANY method.
It's not that any() is a reserved method, it's that the class is using overloading to call that method. Look at this code for a second
/**
* Defines a route w/ callback and method
*
* #param string $method
* #param array #params
*/
public static function __callstatic($method, $params){
$uri = dirname($_SERVER['PHP_SELF']).'/'.$params[0];
$callback = $params[1];
array_push(self::$routes, $uri);
array_push(self::$methods, strtoupper($method));
array_push(self::$callbacks, $callback);
}
When any() is called, PHP first checks for that method being defined directly. Since it's not, it then calls this overloading magic method, which then executes the call.

Categories