"encapsulate" a whole part in a html query? - php

It might sound odd, but I want to send "hierarchical" html-query's == queries that contain queries and sub-queries (to a PHP based system).
The idea is that the first parse_str() will just convert the "outer part" into an array leaving all the "inner party untouched (unlike it is done with %26 that is converted to "&" anywhere).
So, what I search for is kind of a "escape begin / escape end" type of char(s) that make the HTML parser to leave all inside the escape untouched.
Therefor, the "first" parse would deliver an array of queries (and values, if these are not "escaped").
Basically I my ideal query would look like this - where "{" and "}" are the escape begin/end chars:
"key1=abc&query[]={this_is_a_query}&query[]={and_yet_another}"
where {this_is_a_query} would be: "k1=abc&k2=100" and {and_yet_another} would be "k1=xyz&k2=200".
So, fully written:
"key1=abc&query[]={k1=abc&k2=100}&query[]={k1=xyz&k2=200}"
As a result, i would like to get an assoc array that holds "parsable" values that are queries themselfs:
key1=>abc
query[0] => "k1=abc&k2=100"
query[1] => "k1=xyz&k2=200"
I know that I can do that with "%26", but that only works in the "first hierarchy", but not for "queries/in-queries/in-queries" (and so forth)
What I want to achieve is kind of a "batch query" that allows for running multiple programs with one single call.
I hope my description above is understandable?
Sorry, it looks like I did not well express mself. To clearify, I wtry to mak another example, think about parse_str() would have "{}" as chars enclosing what it should not touch:
received string:
step[]={scene[]={dim=10&item=kitchenlamp}&scene[]={item=sprinkler&state=on}}&step[]=delay=20&step[]={scene[]={item=sprinkler&state=off}}
first parse_str would return:
step[0]=>scene[]={dim=10&item=kitchenlamp}&scene[]={item=sprinkler&state=on}
step[1]=>delay=20
step[2]=>scene[]={item=sprinkler&state=off}
My function would now iterate the steps 0..1..2 and hand over the values to the next function that also uses parse_str to aquire it's parameters and so forth.
The sub-function of step 1 would itself get an array and loop it ... apssing the parameters to the "scene" function that itself would dismantle the parameters of what to be done
step 2 would be a direct execution ... wait 10 seconds
step 3 would again get an array of scenes that it would hand over to the scene function.
I hope it's more clear now, what my direction goes to.
Especially that there are same "keys" for some different parts of the "action chain string".
Why I want it this way is the fact that 1.) the sending device has no similar function like http_build_query 2.) the parameters shall be entered by users (not programmers) in an INI-like file.

One way of doing it would be to urlencode the whole "part":
$part="key1=abc&query[]={k1=abc&k2=100}&query[]={k1=xyz&k2=200}";
$href="https://somepage.com?part=".urlencode($part);
// this will result in
// https://somepage.com?part=key1%3Dabc%26query%5B%5D%3D%7Bk1%3Dabc%26k2%3D100%7D%26query%5B%5D%3D%7Bk1%3Dxyz%26k2%3D200%7D
see a little demo here: https://rextester.com/NLBOA61240
Alternatively you could also json_encode() it:
$part=["key1"=>"abc","query"=>[["k1"=>"abc","k2"=>100],["k1"=>"xyz","k2"=>200]]];
$href="https://somepage.com?part=".urlencode(json_encode($part));
On the receiving end you can then easily json_decode() the string you get in $part.
see here: https://rextester.com/UZGV97528

Related

Adding characters to str_replace in PHP

I have a php file with thread ($tid) and post ($pid) ids defined and I'm looking to use str_replace to combine them and create my desired output (below) with &p= added:
Desired output:
$tid&p=$pid
The closest I've got is doing this:
$tid=$t1;
$pid=$p1;
$tid=str_replace("$tid","$tid"."$pid",$tid);
The result is:
$tid$pid
I may need to use a function (not sure which if so?) in the str_replace to support the &p= being added, as trying to add it in the quotes directly doesn't seem to work resulting only in database errors.
Edit #1: I tried doing the following based on the comments thus far:
$tid="";
$tid.="$t1";
$tid.="$p1";
$tid=$tid;
That results in the same as my previous example above:
$tid$pid
As soon as I add another with the &p= I get a database error:
$tid.="&p=";
So my question now is how to add the &p= to my Edit #1 example above correctly?
I'm attempting to understand the question a little bit. You have a couple options that are alluded to in the comments above. You could, for instance (where '1', '2', and '3' are replaced by the desired values):
<?php
$tid=1;
$pid=2;
$amp=3;
$tid=str_replace("$tid","$tid".'$amp;p='."$pid",$tid);
echo $tid;
?>
Here you can just explicitly state in the 'replace' argument of str_replace that the missing string should be part of the replacement string.
or you could also simply use the a concatenation operator to generate the string you desire which is probably simpler given what (little) I know of the surrounding code/use-case:
<?php
$tid=1;
$pid=2;
$amp=3;
echo "$tid".'$amp;p='."$pid";
?>
The reason I'd recommend the latter, is due to the fact that it's less resource intensive to actually produce the desired result which appears to just be a string. str_replace() searches the "haystack" or subject string using the search string and then must replace each of the found instances with the replace string.

How to choose between explode and regex

My string is to contain some "hotkeys" of the form [hotkey]. For example:
"This is a sample string [red] [h1]"
When I process this string with a php function, I'd like function to output the original string as follows;
<font color='red'><h1>This is a sample string</h1></font>
I'd like to use this function purely for convenience purposes easing some typing. I may use a font tag or div or whatever, let's not get into that. The point is this; a hotkey will cause the original string to be wrapped into
<something here>original string<and something there>
So the function first needs to determine if there are any hotkeys or not. That's easy; just check to see if there is any existence of [
Then we will need to process the string to determine which hotkeys exist and get into the biz logic as to which wrappers to be deployed.
and finally we will have to clean the original string from the hotkeys and return the results back.
My question is if there is a regex that would make this happen more effectively then the following parsing method that I am planning of implementing the function as.
step 1
explode the string into an array using the [ delimiter
step 2
go thru each array element to see if the closing ] is present and it forms one of the defined hotkeys, and if so, do the necessary.
Obviously, this method is not using any regex power. I'm wondering if regex could be of help here. Or, any better way to do it you may suggest?
If [ and ] are the only delimeters you need to worry about, you could probably use strtok
I don't speak english well but I saw your example :
"This is a sample string [red] [h1]"
<font color='red'><h1>This is a sample string</h1></font>
If I were you :
$red = substr( $chaine, strpos($chaine, '['), strpos($chaine, ']') );

PHP - Exploding on character(s) that can NEVER be user-defined... How?

Ok, am trying to find a character or group of characters, or something that can be used that I can explode from, since the text is user-defined, I need to be able to explode from a value that I have that can never be within the text.
How can I do this?
An example of what I'm trying to do...
$value = 'text|0||#fd9||right';
Ok,
text is something that should never change in here.
0, again not changeable
#fd9 is a user-defined string that can be anything that the user inputs...
and right sets the orientation (either left or right).
So, the problem I'm facing is this: How to explode("||", $value) so that if there is a || within the user-defined part... Example:
$value = 'text|0||Just some || text in here||right';
So, if the user places the || in the user-defined part of the string, than this messes this up. How to do this no matter what the user inputs into the string? So that it should return the following array:
array('text|0', 'Just some || text in here', 'right');
Should I be using different character(s) to explode from? If so, what can I use that the user will not be able to input into the string, or how can I check for this, and fix it? I probably shouldn't be using || in this case, but what can I use to fix this?
Also, the value will be coming from a string at first, and than from the database afterwards (once saved).
Any Ideas?
The problem of how to represent arbitrary data types as strings always runs up against exactly the problem you're describing and it has been solved in many ways already. This process is called serialization and there are many serialization formats, anything from PHP's native serialize to JSON to XML. All these formats specify how to present complex data structures as strings, including escaping rules for how to use characters that have a special meaning in the serialization format in the serialized values themselves.
From the comments:
Ok, well, basically, it's straight forward. I already outlined 13 of the other parameters and how they work in Dream Portal located here: http://dream-portal.net/topic_122.0.html so, you can see how they fit in. I'm working on a fieldset parameter that basically uses all of these parameters and than some to include multiple parameters into 1. Anyways, hope that link helps you, for an idea of what an XML file looks like for a module: http://dream-portal.net/topic_98.0.html look at the info.xml section, pay attention to the <param> tag in there, at the bottom, 2 of them.
It seems to me that a more sensible use of XML would make this a lot easier. I haven't read the whole thing in detail, but an XML element like
<param name="test_param" type="select">0:opt1;opt2;opt3</param>
would make much more sense written as
<select name="test_param">
<option default>opt1</option>
<option>opt2</option>
<option>opt3</option>
</select>
Each unique configuration option can have its own unique element namespace with custom sub-elements depending on the type of parameter you need to represent. Then there's no need to invent a custom mini-format for each possible parameter. It also allows you to create a formal XML schema (whether this will do you any good or not is a different topic, but at least you're using XML as it was meant to be used).
You can encode any user input to base64 and then use it with explode or however you wish.
print base64_encode("abcdefghijklmnopqrstuvwxyz1234567890`~!##$%^&*()_+-=[];,./?>:}{<");
serialized arrays are also not a bad idea at all. it's probably better than using a comma separated string and explode. Drupal makes good use of serialized arrays.
take a look at the PHP manual on how to use it:
serialize()
unserialize()
EDIT: New Solution
Is it a guarantee that text doesn't contain || itself?
If it doesn't, you can use substr() in combination with strpos() and strrpos() instead of explode
Here's what I usually do to get around this problem.
1) capture user's text and save it in a var $user_text;
2) run an str_replace() on $user_text to replace the characters you want to split by:
//replace with some random string the user would hopefully never enter
$modified = str_replace('||','{%^#',$user_text);
3) now you can safely explode your text using ||
4) now run an str_replace on each part of the explode, to set it back to the original user entered text
foreach($parts as &$part) {
$part = str_replace('{%^#','||',$part);
}

Consolidating multiple GET parameters into a single value

Im not really sure what im looking for but currently in my system i send a long url like this:
$name=1&option=2&field=4....
And its quite long. So if i have a list of values like:
name
option
field
can i put them into a string in which i can break at certain points eg by a slash or whatever.
And then encode the string so its completely random like, so i only have one field to send:
&data=JKHFGDKGLKJHFKDJHFKJDHFKHDF
Then finally i can decode the other side and break apart.
Is there a pre-built function to do this?
WHAT IT IS:
im sending data to paypal, but i have a few custom variables i wish to send, now for some reason my IPN isnt geting them, not sure why, but if i add one called custom it get to the IPN fine. So i thought if i just send one called custom in a random format and then decode?
You could simply Base64-encode your data.
$a = array('name' => '1', 'option' => '2', 'field' => '4');
$temp = json_encode($a); // convert array to string
$data = base64_encode($temp); // encode string
output:
"eyJuYW1lIjoiMSIsIm9wdGlvbiI6IjIiLCJmaWVsZCI6IjQifQ=="
To send this in an URL, you must encode it once more (like you must encode all data you would send in a URL)
$url = $url . "&data=" . urlencode($data)
The intermediary step through JSON ensures your data will kep its structure and will be easily decodeable on the receiving side.
On the downside: Your URL will be longer.
Use base64_encode and then base64_decode, this will solve your problem.
If you don't know what you are looking for we can't imagine that lol.
Anyway If i got you, you can do this, considering you have built your string:
$string ="$name=1&option=2&field=4";
You could pass it as a single param with:
$data = url_encode($string);
Other than url_encode you can use base64_encode
As the commenter (Bobby) says - consider using POST when you want to send larger sets of data and prevent your URL from becoming unmanageably long or ugly.
GET variables are handy for providing the user with a page they can bookmark directly which is desirable in some cases, such as on a search page with a query string and/or filters already filled in, so that the user can return to a search and check for new results periodically without having to reset all of their choices.
POST variables are better if you don't need that sort of functionality, you don't need to encode/decode them for URLs and they can't be bookmarked directly (which is also desirable in many cases).
To answer your original question though, if you really, really had to send the variable(s) on the URL and you wanted to just send one apparently random string, I suggest writing a couple of encode/decode functions of your own (since I assume the object of the excercise is not to encrypt it against tampering, just to make your URLs friendlier). This will be all the easier if there are restrictions to what the variables can be, and more difficult if they can be absolutely anything.
For example - if you have the following vars and possible settings:
var1 (apple, banana, orange)
var2 (car, motorbike, bicycle)
var3 (red, yellow, green)
Normally, you'd make a URL like:
http://www.mysite.com/page.php?var1=banana&var2=car&var3=green
If you assign the variables to numbers (for example) so that var1, var2 and var3 would be 1, 2 or 3 - then you could send over a URL like:
http://www.mysite.com/page.php?vars=213
Break it down at the other end into single numbers and convert those back into 'banana', 'car', and 'green'.
But seriously.... I'd look at POST first unless there is very specific reason why you would use this sort of approach - i've used it before for shortening a URL to make it more sharable on social media and forums.

What to use as array_import/var_import for sort-of exported array?

I have a string. It's a user submitted string. (And you should never ever trust user submitted anything.)
If certain (not unsafe) characters exist in the string, it's supposed to become a multi dimensional array/tree. First I tried splits, regex and loops. Too difficult. I've found a very easy solution with a few simple str_replace's and the result is a string that looks like an array definition. Eg:
array('body', array('div', array('x'), array(), array('')), array(array('oele')))
It's a silly array, but it's very easily created. Now that string has to become that array. I'm using eval() for that and I don't like it. Since it's user submitted (and must be able to contain just about anything), there could be any sort of function calls in that string.
So the million dollar question: is there some kind of var_import, or array_import that creates an array from a string and does nothing else (like mysterious, dangerous calls to exec etc)?
Yes, I have tried php.net and neither of the above _import functions exist.
What I'm looking for is the exact opposite of var_import, becasuse the string I have as input, looks exactly like the string var_export would output.
Any other suggestions to make it safer then eval are also welcome! But I'm not abandoning the current method (it's just too simple).
Using
array('body', array('div', array('x'), array(), array('')), array(array('oele')))
as input, I replaced some chars to make it a valid JSON string and imported that via json_decode.
Works perfectly. If some illegal chars are present, json_decode will trip over them (and not execute any dangerous code).

Categories