list and explode
Asked Answered
H

8

8

I am trying to use url rewriting on my website and I want to use the list() and explode() functions to get the right content. Currently my code looks like this:

list($dir, $act) = explode('/',$url);

In this case $url is equal to everything after the first slash in the absolute url i.e. http://example.com/random/stuff => $url = random/stuff/ this would work fine, but if I want to go to http://example.com/random/ then it will print a notice on the page. How do I stop the notice from showing up do I need to use something other than the list() function?

Right now the notice is "Notice: Undefined offset: 1..."

Thanks for the help!

Hyalo answered 1/3, 2010 at 18:14 Comment(1)
Fixes for this issue aside, you should turn off the display of PHP errors on your production site.Livi
L
12

You should check how many path segments the URL contains:

$segments = explode('/', $url);
if (count($segments) !== 2) {
    // error
} else {
    list($dir, $act) = $segments;
}

But maybe you should choose a more flexible approach than using list.

Levo answered 1/3, 2010 at 18:18 Comment(3)
What would be an example of a more flexible approach?Hyalo
@TheGNUGuy: That depends on your requirements, how your application expect to receive its arguments.Levo
I adapted your solution above to use a switch statement so more easily deal with multiple different cases. Thanks!Hyalo
Y
28

Try this :

list($dir, $act) = array_pad(explode('/',$url), 2, '');

array_pad complete the array with your values, here is : ''.

Yak answered 10/11, 2014 at 13:28 Comment(2)
list($a, $b, $c) = explode('/', $url) + ['x', 'y', 'z']; to have different defaults.Stercoricolous
The solution of @Stercoricolous looks also pretty nice. My suggestion with single default values list($a, $b, $c) = explode('/', $url . '//');Foregather
L
12

You should check how many path segments the URL contains:

$segments = explode('/', $url);
if (count($segments) !== 2) {
    // error
} else {
    list($dir, $act) = $segments;
}

But maybe you should choose a more flexible approach than using list.

Levo answered 1/3, 2010 at 18:18 Comment(3)
What would be an example of a more flexible approach?Hyalo
@TheGNUGuy: That depends on your requirements, how your application expect to receive its arguments.Levo
I adapted your solution above to use a switch statement so more easily deal with multiple different cases. Thanks!Hyalo
B
4

Check out parse_url

Bloodhound answered 1/3, 2010 at 18:28 Comment(1)
This link-only answer is low-value.Electroanalysis
F
1

A solution would be to split your line of code in several, to ensure you never assign non-existing values to variables -- which is what you are doing when explode only returns one portion of URL.

For that, not using list seems like the right solution, as, with list, you must know how many elements the expression on the right of = will return...
And, in this situation, you don't know how many elements explode will return.


For instance, something like this might be OK :

$parts = explode('/', $url);
if (isset($parts[0])) {
  $dir = $parts[0];
  if (isset($parts[1])) {
    $act = $parts[1];
  }
}

Of course, up to you to deal with the situation in which $dir and/or $act are not set, later in your script.


Another solution would be to check how many elements explode will return (counting a number of / for instance) ; but you'll still have to deal with at least two cases.

Fluffy answered 1/3, 2010 at 18:18 Comment(0)
E
1

to get rid of the notice:

list($dir, $act) = explode('/',$url);

but maybe a better solution would be:

$segments = explode ('/', $url);
$dir = array_shift ($segments);
$act = array_shift ($segments);

if there is no 2nd segment, $act would be null and you can also more than 2 segment this way

Ennis answered 1/3, 2010 at 18:22 Comment(0)
L
0

Instead of exploding the full URL, try $_SERVER['PATH_INFO'], assuming '/random' names the script.

Letourneau answered 1/3, 2010 at 18:19 Comment(1)
Downvoter: what's wrong with PATH_INFO? The question is ambiguous enough to allow for this possibility.Letourneau
L
0

The correct way to suppress the E_NOTICE on list assignment as of PHP 5.4+ is the following:

@list($dir, $act) = explode('/', $url);

If $url contains no /, explode will return one element and $act will be NULL.

Lanky answered 6/12, 2016 at 9:4 Comment(0)
I
-1

The simple and ugly answer is to prefix the whole thing with a single '@' which suppresses error outputs. $act will be set to null in that case because under the hood, it's equivalent to:

$foo = explode('/',$url);
$dir = $foo[0];
$act = $foo[1]; // This is where the notice comes from
Incision answered 1/3, 2010 at 18:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.