PHP regex remove prepend content before dot - php

I have in PHP an array string which contain stuff like this:
$a = array(
array('inner' => 'N.person = P.id'),
array('inner' => 'L.person = P.id'),
array('left' => 'A.person = P.id AND A.excluded IS NULL')
);
And I want to inform primary key P.id and remove all alias from sql resulting in something like this:
$x = someFunctionThatSanitizeSQL('P.id', $a);
print_r on $x result:
array(
array('inner' => 'person = :pk'),
array('inner' => 'person = :pk'),
array('left' => 'person = :pk AND excluded IS NULL')
);
Thanks in advance
#edit: miss a typo

After doing a str_replace($pkreplace, ':pk', $mystring);, the regex I think you're looking for is something like:
/(?=(^|\w))[A-Z0-9_-]+\./
For example, to clean out each string, you can do
preg_replace('/(?=(^|\w))[A-Z0-9_-]+\./i', '', $mystring);
However, if you are removing the A., L., etc., there may be other issues with your query due to the values no longer being under the database tables and possibly causing ambiguous value errors. Are you certain this is the behavior you want in your queries?
EDIT
A final implementation of your function would look something like (assuming you need arrays):
function someFunctionThatSanitizeSQL($pkreplace, $dataarray) {
if (!is_array($dataarray))
return null;
$retval = array();
foreach ($dataarray as $key => & $curentry) {
$curstring = str_replace($pkreplace, ':pk', $curentry);
$curstring = preg_replace('/(?=(^|\w))[A-Z0-9_-]+\./i', '', $curstring);
$retval[$key] = $curstring;
}
return $retval;
}

Related

usesort not working in case sensitive string that is grabbed by explode function

This code works great, until something is case sensitive. I've tried using strnatcasecmp instead of the cmp, and it grabs the whole string not the last name. any suggestions on how to write this better?
for example the current order is:
Aaron Carson
Adam Davidson
Jen Hennings
ektor bluemouth
I want ektor bluemouth to be on top.
foreach($connected->posts as $p) {
$lastname = explode(' ', $p->post_title);
if(sizeof($lastname) == 1) {$p->lastname = $lastname[0];}
if(sizeof($lastname) == 2) {$p->lastname = $lastname[1];}
if(sizeof($lastname) == 3) {$p->lastname = $lastname[2];}
}
usort($connected->posts, 'cmp');
I would do something like this
$aPosts = array(
array('post_title' => 'Aaron Carson'),
array('post_title' => 'Adam Davidson'),
array('post_title' => 'Jen Hennings'),
array('post_title' => 'ektor bluemouth'),
);
$aOrderedPosts = array();
foreach($aPosts as $iPos => $p){
$a = explode(' ', $p['post_title']);
// cast the last name to lowercase and assign by reference the post
$aOrderedPosts[strtolower($a[1])] =& $aPosts[$iPos];
}
var_dump($aOrderedPosts);
// perform a key sort
ksort($aOrderedPosts);
var_dump($aOrderedPosts);
It could be adapted to work with your data format
$aOrderedPosts = array();
foreach($connected->posts as $iPos => $p){
$a = explode(' ', $p->post_title);
$aOrderedPosts[strtolower($a[1])] =& $connected->posts[$iPos];
}
ksort($aOrderedPosts);
var_dump($aOrderedPosts);
Best to create $aOrderedPosts when you create/read in the post objects from DB. Additionally I would create it as a property of the connection class.

Array get specific field

I have a variable in WordPress (using Visual Composer plugin template)
$posts_query = $settings['posts_query']
and when i print_r
print_r($posts_query);
results on this:
size:4|order_by:date|post_type:donation_slider|post_status:publish
How can i get the field post_type?
I tried with $posts_query['post_type'] but it just shows letter "s" or $posts_query->post_type; it shows blank!
Any thoughts?
This is an atypical situation, and an atypical way to store information. It looks like someone decided to invent their own serialization storage (storing an array in a string).
To access the information you want, you'll need to manipulate the string into the various array components, using explode.
Here's some code to get you started:
// $posts_query is equal to "size:4|order_by:date|post_type:donation_slider|post_status:publish"
$parts = explode('|', $posts_query);
// now parts is an array: ['size:4', 'order_by:date', 'post_type:donation_slider', 'post_status:publish'
$array = [];
// loop over the exploded parts
foreach( $parts AS $part ) {
// split the sub-parts apart
$split = explode(':', $part);
// glue it into a proper associative array
$array[$split[0]] = $split[1];
}
Now you have an array that should look like this:
array(
'size' => 4,
'order_by' => 'date',
'post_type' => 'donation_slider',
'post_status' => 'publish'
)
Which you can access each separate part like so:
$post_type = $array[ 'post_type']; // returns "donation_slider"
I do not know WordPress very well but the native PHP way to do this is like this:
$posts_query = 'size:4|order_by:date|post_type:donation_slider|post_status:publish';
foreach( explode( '|', $posts_query ) as $pairs )
{
if( explode( ':', $pairs )[0] === 'post_type' )
{
echo explode( ':', $pairs )[1];
break;
}
}
Looks like an imploded string. The elements are separated by |, and keys and values are separated by :. You can use explode to create the array you want:
$array = [];
foreach( explode($posts_query, '|') as $keyVal) {
$tmp = explode($keyVal, ':');
$array[$tmp[0]] = $tmp[1];
}
Then you can use array like you did in your question.
I found this solution:
$post_type_query = explode("|", $posts_query);
$post_type = str_replace("post_type:","",$post_type_query[2]);
and it print the value of post_type.
Thank you so much for your help guys, i appreciate that!
An alternative solution:
It appears that $posts_query is a string so accessing it like an array won't pull out the 'post_type'.
You could try using this function (Source: http://php.net/manual/en/function.explode.php), this makes a new array out of $posts_query with | being the separator between data fields and : being the separator between key and value. Then you can get post_type like $parsed_posts_query['post_type'] as shown.
function explode_with_keys($delim1,$delim2,$inputstring)
{
$firstarr = explode($delim1,$inputstring);
$finalarr = array();
foreach($firstarr as $set)
{
$setarr = explode($delim2,$set);
$finalarr[$setarr[0]] = $setarr[1];
}
return $finalarr;
}
$parsed_posts_query = explode_with_keys("|",":",$posts_query);
print_r($parsed_posts_query['post_type']);

PHP: Set value of nested array using variable as key

Lets say i have this kind of code:
$array = [
'a'=> [
'b' => [
'c'=>'some value',
],
],
];
$array['a']['b']['c'] = 'new value';
Of course this is working, but what i want is to update this 'c' key using variable, something like that:
$keys = '[a][b][c]';
$array{$keys} = 'new value';
But keys are treatening as string and this is what i get:
$array['[a][b][c]'] = 'new value';
So i would like some help, to show me the right way to make this work without using eval().
By the way, there can be any number of array nests, so something like this is not a good answer:
$key1 = 'a';
$key2 = 'b';
$key3 = 'c';
$array[$key1][$key2][$key3] = 'new value';
It isn't the best way to define your keys, but:
$array = [];
$keys = '[a][b][c]';
$value = 'HELLO WORLD';
$keys = explode('][', trim($keys, '[]'));
$reference = &$array;
foreach ($keys as $key) {
if (!array_key_exists($key, $reference)) {
$reference[$key] = [];
}
$reference = &$reference[$key];
}
$reference = $value;
unset($reference);
var_dump($array);
If you have to define a sequence of keys in a string like this, then it's simpler just to use a simple separator that can be exploded rather than needing to trim as well to build an array of individual keys, so something simpler like a.b.c would be easier to work with than [a][b][c]
Demo
Easiest way to do this would be using set method from this library:
Arr::set($array, 'a.b.c', 'new_value');
alternatively if you have keys as array you can use this form:
Arr::set($array, ['a', 'b', 'c'], 'new_value');
Hi bro you can do it like this throught an array of keys :
This is your array structured :
$array = array(
'a'=> array(
'b' => array(
'c'=>'some value',
),
),
);
This is the PHP code to get value from your array with dynamic keys :
$result = $array; //Init an result array by the content of $array
$keys = array('a','b','c'); //Make an array of keys
//For loop to get result by keys
for($i=0;$i<count($keys);$i++){
$result = $result[$keys[$i]];
}
echo $result; // $result = 'new value'
I hope that the answer help you, Find here the PHPFiddle of your working code.

Possibility of passing multiple parameters in URL?

I'm working on a search-based website, and am trying to pass parameters using SEO-friendly URLs.
Is it possible to pass the following URL and get the URL in CodeIgniter?
http://www.example.com/search/prize/10/13/14.5/size/xl/2xl/color/black/white-grey/
I am able to create the URL, but I want to get the URL values like $prize = array("10","13","14.5"), $size= array("xl","2xl"), and $color = array("black","white-grey").
I tried to use the uri_to_assoc() function, but it didn't work. I get the following output:
[price] => 10,
[13] => 14.5
...
which is wrong.
Note: I tried to use $this->uri->segment(1), etc., but in this case, the segment position is dynamic.
For example, users may search for only prices of $10, so the URL will get changed to:
http://www.example.com/search/prize/10/size/xl/2xl/color/black/white-grey/
Now the segment position of getting the size must be changed. In this case, I want:
$prize = array("10");
$size = array("xl", "2xl");
$color = array("black", "white-grey");
How can I achieve this?
You are using quite the unconventional "friendly URI" format. Normally when passing parameters there is a single identifier and then the parameter e.g. /name/key/name/key/name/key.
When you use the correct format /name/key/name/key/name/key in conjunction with uri_to_assoc(), you would get:
array(
'name' => 'key',
// etc...
)
but using something like /prize/1/2/3/size/s/m/l/color/black/white/grey would yield:
array(
'prize' => 1,
2 => 3,
'size' => 's',
'm' => 'l',
// etc...
)
Which is useless to you.
You will have to fetch all of the segments individually and build your arrays with a foreach:
$segments = $this->uri->segment_array();
$prize = array();
$size = array();
$color = array();
$curKey = '';
foreach ($segments as $seg) {
if (in_array($seg, array('prize', 'size', 'color'))) {
$curKey = $seg; continue;
}
if (!empty($curKey)) ${$curKey}[] = $seg;
}
// use $prize, $size, and $color as you wish
or alternatively using a multi-dimensional array:
$parameters = array(
'prize' => array(),
'size' => array(),
'color' => array(),
);
$segments = $this->uri->segment_array();
$curKey = '';
foreach ($segments as $seg) {
if (in_array($seg, array('prize', 'size', 'color'))) {
$curKey = $seg; continue;
}
if (!empty($curKey)) $parameters[$curKey][] = $seg;
}
Fetch all the segments
Iterate over them, check each for keywords like size, color, etc. (make a whitelist)
If a keyword is found, assume the segment values until the next keyword segment or the end are the values for that specific keyword (so xl and 2xl will denote the size if preceeded with a keyword size, etc.)

how to change illegal characters in php extract function?

I needed to extract key-value pairs from the following array into variables
$data = array(
'Quotation.id' => 1,
'Quotation.project_id' => 2
);
extract($data);
Because the . is an illegal character in PHP, no extra variables are defined when I run extract.
I would like to somehow remove the dots and change the entire field into a camelCase. Meaning to say, without knowing in advance the keys in $data, I would like to somehow get back as newly-defined variables:
$quotationId = 1;
$quotationProjectId = 2;
How do I accomplish this?
Please ignore situations where the newly-defined variables may clash with existing variables. Assume this will not happen.
There is probably an easier way with regular expressions, but this is how I would do it:
foreach ($data AS $k => $v) {
$key = str_replace(' ', '', ucwords(str_replace('.', ' ', $k)));
${$key} = $v;
}
You may try this
<?php
$data = array(
'Quotation.id' => 1,
'Quotation.project_id' => 2
);
foreach($data as $key=>$value) {
$keys = array_map('ucfirst',preg_split( "/(\._)/", $key ));
$newKey = implode($keys);
unset($data[$key]);
$data[$newKey] = $value;
}
export($data);
?>

Categories