Parsing url with preg_match - regexp - php

I've trying to make my own route class - and I've hot problem with parsing valid url's.
This is an example url:
http://localhost/app/module/command/i15
And I need every element after slash / to be an additional element in array creating using preg_match in php.
So - for searching of numbers I've got: ([0-9]+)
Searching strings that contains letters, signs like - or _ I've got ([^.]+) (here's the problem)
whole regexp looks like this:
(app)\/(module)\/([^.]+)\/i([0-9]+)
i want an array of 5 elements, something like that:
0 => app, 1=> module, 2 => command, 3 => i15
It will be more beauty if preg_match will return only something like that:
0 => app, 1=> module, 2 => command, 3 => 15 (without I as param identifier)
Can anyone quick help me with this ? I stuck 2 days in that, and can't find right solution.
EDIT:
I've got some regexp predefined like:
/app/contacts/list => (app)\/(contacts)\/([^.]+)
/app/contacts/edit/i15 => (app)\/(contacts)\/([^.]+)\/i([\d]+)
/app/contacts/view/i15-c2 => (app)\/(contacts)\/([^.]+)\/i([\d]+)-c([\d]+)
And for all of those I prepare different regexp like above. Problem stars when I need to parse something between:
/app/contacts/preview/random-name/i15-c2
or
/app/contacts/preview/random-name-i15-c2
([^.]+) catches also \ (slash) - and in above first example this slash broke whole regexp :-(
EDIT SECOND TIME :-)
I've got some predefined regexps for some paths. Lets have a look:
$regexp = [
[0 => '(app)\/([^/]+)'],
[1 => '(app)\/([^/]+)\/i([0-9]+)']
];
Next i check current url and match the best result - I know what I want, but php doesn't know what user select so:
if I enter url with path:
app/username/i15
System shows me that $regexp[0] is best result - what it is not true, because $regexp[1] are the best.
I hope this explains my problem.

Since you're using groups to capture in your regex, you can use them to create your desired array. Pass a variable to preg_match() to store the groups:
$components = [];
preg_match('#(app)/(module)/([^.]+)/i([0-9]+)#', $uri, $components);
Now the first element of $components is the whole match, and then the groups.
array_shift($components); # discard first element

Ok heres class for my routing:
https://gist.github.com/djmassive/d7487cef92e3adb1abf7ca31d3e96a53
Whole magic are done in method parse()
I've adding routings:
$route->get('(app)\/:string', [ 'schema' => '2', 'module' => 'system', 'file' => 'profile' ]);
$route->get('(app)\/:string\/i:id', [ 'schema' => '2,3', 'module' => 'system', 'file' => 'profile', 'command' => 'view' ]);
schema define what I want to be na id - it can be int, string or array.
module is folder name
file is filename
command is command use in file for show directly what I want
If I had url:
app/list - system reads it like that:
$command is list (schema shows second element) - works
app/username/i15
$command should be view
$id should be [ username, 15 ]
in this case, first regexp is showing 66% of match like second one - but second one should be 100%
Have a look at debuging:
Checking regexp: #(app)\/([^/]+)# - to match path: app/username/i15
Results preg_match \$matches array:
Array ( [0] => app/username [1] => app [2] => username )
Percentage match: 66.6666666667%
Checking regexp: #(app)\/([^/]+)\/i([\d]+)# - to match path: app/username/i15
Results preg_match \$matches array:
Array ( [0] => app/username/i15 [1] => app [2] => username [3] => 15 )
Percentage match: 66.6666666667%
we see, that first regexp are not good because there are not third element.
From what I know, the whole problem is mainly to not return what does not meet the full condition.

Related

preg_match from URL string

I have a string passed through a campaign source that looks like this:
/?source=SEARCH%20&utm_source=google&utm_medium=cpc&utm_term=<keyword/>&utm_content={creative}&utm_campaign=<campaign/>&cpao=111&cpca=<campaign/>&cpag=<group/>&kw=<mpl/>
when its present I need to cut this up and pass it through to our form handler so we can track our campaigns. I can check for it, hold its contents in a cookie and pass it throughout our site but i am having and issue using preg_match to cut this up and put it into variables so I can pass their values to the handler. I want the end product to look like:
$utm_source=google;
$utm_medium=cpc;
$utm_term=<keyword/>
there is no set number of characters, it could be Google, Bing etc, so i am trying to use preg_match to get the first part (utm_source) and stop past what I want (&) and so forth but I don't understand preg_match well enough to do this.
PHP should be parsing your query sting for you, into $_GET. Otherwise, PHP knows how to parse query strings. Don't use regular expressions or for this, use parse_str.
Input:
<?php
$str = "/?source=SEARCH%20&utm_source=google&utm_medium=cpc&utm_term=<keyword/>&utm_content={creative}&utm_campaign=<campaign/>&cpao=111&cpca=<campaign/>&cpag=<group/>&kw=<mpl/>";
$ar = array();
parse_str($str, $ar);
print_r($ar);
Output:
Array
(
[/?source] => SEARCH
[utm_source] => google
[utm_medium] => cpc
[utm_term] => <keyword/>
[utm_content] => {creative}
[utm_campaign] => <campaign/>
[cpao] => 111
[cpca] => <campaign/>
[cpag] => <group/>
[kw] => <mpl/>
)

navigate through huge nested array in PHP

This might be a simple question, but I am dumping an object ($this) which is absolutely huge and I need to get to a specific point in the array
$this->varA->varB->varC->varD->what_I_need
I know that the variable that I need is in there and I can use ctrl+f to find it, but the array is so nested that I don't know how I should get to it in PHP. Any ideas on what the best way is to do this?
Do not hesitate to look at libraries from frameworks.
[CakePHP] made an awesome class which is able to navigate into arrays using a string in dot syntax notation. This library is known as Hash, just look at it.
If you have this :
$var = array(
'Element1' => array(
'First_rule' => true,
'Second_rule' => false,
),
'Element2' => array(
'First_rule' => 'none',
'Other_rule' => 'otherone',
),
);
You can extract datas from this array simply with a string.
You can take only one information from a specific element :
$extracted_other_rule = Hash::extract($var, 'Element2.Other_rule');
Returns :
Array
(
[0] => otherone
)
Or you can even extract all "First_rule" indexes from any element in the array containing it :
$extracted_rules = Hash::extract($var, '{s}.First_rule');
Returns this :
Array
(
[0] => 1
[1] => none
)
If you need to navigate through a huge array with undefined depth, just make a recursive function, transferring a string named "$path" to recursive actions. I made a big function of this kind to parse a whole XML stream into a JSON string with all keys parsed with my own rules, with an array of parameters.

Failing preg_match pattern over entirely valid value

I used regexpal.com to test my regexp against the data Wordpress is trying to compare to and it fails, look at this and tell me if you see the problem?
The regexp
"#^json/(.+?)/?([a-zA-Z0-9]*)?$#"
The content to match
json/trips
These works, the previous one doesn't
json/trips/0
json/trips/13
json/fullticket/9805048001130122361809
If I try all these in regexpal they all work, but in wordpress, only the one that doesn't contain the id of the element I want to fetch fails the others work fine.
Interrestingly enough, the $matches return this:
array
0 => string 'json/trips' (length=10)
1 => string 't' (length=1)
2 => string 'rips' (length=4)
Try this regexp instead :
#^json/([^/]+)/?([a-zA-Z0-9]*)?$#
Output :
Array
(
[0] => json/trips
[1] => trips
[2] =>
)
The answer after tweaking the wordpress rewrite rule a bit more ends up being:
data/([^/]+)(/([a-zA-Z0-9\-]*))?$
Note: i changed json to data in the new scenario so i don't mess up the custom post type rules

PHP parameters Facebook dialog

I have created a very simple script to extract some parameters from the url using:
$_SERVER['QUERY_STRING'];
I have some values like this link:
http://test.com/r.php?gsgsg&0&1&0&sfs
The values are gsgsg 0 1 0 sfs.
Everything is fine when I use the link on own browser.
But when I press the link on a facebook post. I will only get:
gsgs 0 sfs
It seems like facebook removes my numbers.
I tried printing out the url I'm using to post the message in my app, all the values are there. But when I go in Facebook app and press the link, I am missing 2 int values.
Some one have a hint?
A query string like this:
gsgsg&0&1&0&sfs
Is interpreted as:
gsgsg=&0=&1=&0=&sfs=
Just from that you can already imagine that the value of the first 0 gets clobbered by the next. Why Facebook misses the 1 value is unclear, but it's common sense to apply variable naming rules to query string parameters.
I'm not sure what you're trying to do, but this would be much more reliable:
s[]=gsgsg&s[]=0&s[]=1&s[]=0&s[]=sfs
It generates an array $_GET['s'] of:
Array(
[0] => gsgsg
[1] => 0
[2] => 1
[3] => 0
[4] => sfs
)

Put multiple segments of URL in 1 variable with Zend

For a new application I'd like to work with the URI to determine what content should be loaded. Nothing special so far ... But how can I let the slug have slash(es) in it and make sure Zend Framework sees them as 1 variable? ZF splits the requested URL in chunks where every part is the string between 2 slashed. Now I'd like to have all the parts in 1 variable to work with.
For Example:
/de/my/page
de > language
my/page > 1 variable
Any ideas?
Advice from Hari K is the best choice, but if you really want to keep your slash, you can work with a Zend_Controller_Router_Route_Regex to catch your parameter, you just need to find a good regexp, a simple example :
$routetotry = new Zend_Controller_Router_Route_Regex('([^/]+)/(.*)',
array(1 => 'de', 'controller' => 'someController', 'action' => 'someAction'),
array(1 => 'lang',2=>'my_variable_with_slash'),
'%s/%s'
);
$router->addRoute('routetotry', $routetotry);
Custom router. Most flexible solution, but not the easiest one :(
Replace the slashes in the slug with someother value of your choice.
For example hyphen ( - ) or underscore ( _ ) .

Categories