Array get specific field - php

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']);

Related

Replace array value with more than one values

I have an array like this,
$array = array(
1,2,3,'4>12','13.1','13.2','14>30'
);
I want to find any value with an ">" and replace it with a range().
The result I want is,
array(
1,2,3,4,5,6,7,8,9,10,11,12, '13.1', '13.2', 14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30
);
My understanding:
if any element of $array has '>' in it,
$separate = explode(">", $that_element);
$range_array = range($separate[0], $separate[1]); //makes an array of 4 to 12.
Now somehow replace '4>12' of with $range_array and get a result like above example.
May be I can find which element has '>' in it using foreach() and rebuild $array again using array_push() and multi level foreach. Looking for a more elegant solution.
You can even do it in a one-liner like this:
$array = array(1,2,3,'4>12','13.1','13.2','14>30');
print_r(array_reduce(
$array,
function($a,$c){return array_merge($a,#range(...array_slice(explode(">","$c>$c"),0,2)));},
[]
));
I avoid any if clause by using range() on the array_slice() array I get from exploding "$c>$c" (this will always at least give me a two-element array).
You can find a little demo here: https://rextester.com/DXPTD44420
Edit:
OK, if the array can also contain non-numeric values the strategy needs to be modified: Now I will check for the existence of the separator sign > and will then either merge some cells created by a range() call or simply put the non-numeric element into an array and merge that with the original array:
$array = array(1,2,3,'4>12','13.1','64+2','14>30');
print_r(array_reduce(
$array,
function($a,$c){return array_merge($a,strpos($c,'>')>0?range(...explode(">",$c)):[$c]);},
[]
));
See the updated demo here: https://rextester.com/BWBYF59990
It's easy to create an empty array and fill it while loop a source
$array = array(
1,2,3,'4>12','13.1','13.2','14>30'
);
$res = [];
foreach($array as $x) {
$separate = explode(">", $x);
if(count($separate) !== 2) {
// No char '<' in the string or more than 1
$res[] = $x;
}
else {
$res = array_merge($res, range($separate[0], $separate[1]));
}
}
print_r($res);
range function will help you with this:
$array = array(
1,2,3,'4>12','13.1','13.2','14>30'
);
$newArray = [];
foreach ($array as $item) {
if (strpos($item, '>') !== false) {
$newArray = array_merge($newArray, range(...explode('>', $item)));
} else {
$newArray[] = $item;
}
}
print_r($newArray);

Convert a string structured as a Multidimensional Array to array

I have this string:
array(array('1','name1','1','0'),array('2','name2','0','1'),array('3','name3','0','1'),array('4','name4','1','1'),array('5','name5','1','0'));
Stored in $_POST['data']
The string Im receiving is via.load` function where the structure of the string is constructed like so.
I would like to convert it to a multidimensional array via php so I can loop through it easily
So far I`ve reached a workaround by modifying both the string and the method.
Now my string looks like this :
1,name1,1,0,|2,name2,0,1,|3,name3,0,1,|4,name4,1,1,|5,name5,1,0,|
And the method is this
$data2 = $_POST['data2']; /// get data
$data2 = substr_replace($data2 ,"", -2); // eliminate ,|
$data2 = $data2."|"; // add |
$one=explode("|",$data2); // create multidimensional array
$array = array();
foreach ($one as $item){
$array[] = explode(",",$item);
}
I can keep this solution but I would like to know if there is another way of doing it as first requested
There is a better and simple way. You just need to use a foreach loop inside foreach loop.
$data = array(
array('1','name1','1','0'),
array('2','name2','0','1'),
array('3','name3','0','1'),
array('4','name4','1','1'),
array('5','name5','1','0')
);
foreach( $data as $d ) {
foreach( $d as $value ) {
echo $value;
echo '<br />';
}
}
You can check the online Demo
To parse your original string you can use eval()
$string = 'array(array('1','name1','1','0'),array('2','name2','0','1'),array('3','name3','0','1'),array('4','name4','1','1'),array('5','name5','1','0'));';
eval('$array = '.$string);
But eval can/should be disabled on the server, because it comes with security issues.
What i would do is to use JSON, where you would POST the json encoding it with:
json_ecnode( $my_array );
and then decoding it:
$array = json_decode( $_POST['data'], true );

php foreach group results by 3 sets of characters

I am trying to group some foreach results based on the first 3 sets of characters.
For example i am currently listing sku codes for products and they look like this:
REF-MUSBOM-0500-ORA
REF-PROCOF-0001-LAT
REF-WHEREF-0001-TRO
REF-WHEREF-0001-ORA
REF-SHAKER-0700-C/B
REF-CREMON-0100-N/A
REF-GLUSUL-0090-N/A
REF-CRECAP-0090-N/A
REF-ALBFER-0120-N/A
REF-TSHCOT-LARG-BLK
REF-TSHCOT-MEDI-BLK
REF-ALBMAG-0090-N/A
REF-GYMJUG-2200-N/A
REF-OMEGA3-0090-N/A
REF-NEXGEN-0060-N/A
REF-VITAD3-0100-N/A
REF-SSSHAK-0739-N/A
REF-GINKGO-0090-N/A
REF-DIGEZY-0090-N/A
REF-VEST00-MEDI-N/A
REF-VEST00-LARG-N/A
REF-CREMON-0250-N/A
REF-MSM----0250-N/A
REF-GRNTEA-0100-N/A
REF-COLOST-0100-N/A
REF-GLUCHO-0090-N/A
REF-ZINCMA-0100-N/A
REF-BETALA-0250-N/A
REF-DRIBOS-0250-N/A
REF-HMB000-0090-N/A
REF-ALACID-0090-N/A
REF-CLA000-0090-N/A
REF-ACETYL-0090-N/A
REF-NXGPRO-0090-N/A
REF-LGLUTA-0250-N/A
REF-BCAA20-0200-N/A
REF-FLAPJA-0012-ACR
REF-FLAPJA-0012-MAP
REF-LCARNI-0100-N/A
REF-CORDYC-0090-N/A
REF-CREMON-0500-N/A
REF-BCAAEN-0330-APP
REF-PREWKT-0300-FPU
REF-TESFUS-0090-N/A
REF-AMIIFUS-0300-GAP
REF-AMIIFUS-0300-WME
REF-BCAINT-0400-FPU
REF-KRILLO-0090-N/A
REF-AMIIFUS-0300-PLE
REF-AMIIFUS-0300-FPU
REF-BCAINT-0400-WME
REF-ENZQ10-0090-N/A
REF-THERMO-0100-N/A
REF-LGLUTA-0500-N/A
REF-RBAR00-0012-DCB
REF-RBAR00-0012-PBC
REF-RBAR00-0012-WCR
REF-IMHEAV-2200-CHO
REF-PROCOF-0012-N/A
REF-DIEPRO-0900-STR
REF-DIEPRO-0900-BOF
REF-DIEPRO-0900-CHO
REF-INWPRO-0900-VAN
REF-INWPRO-0900-BOF
REF-INWPRO-0900-BCS
REF-INWPRO-0900-CHO
REF-INWPRO-0900-CMI
REF-INWPRO-0900-RAS
REF-INWPRO-0900-STR
REF-INWPRO-0900-CIN
REF-INWPRO-0900-CPB
REF-EGGPRO-0900-CHO
REF-EGGPRO-0900-VAN
REF-MICCAS-0909-CHO
REF-MICCAS-0909-CMI
REF-MICCAS-0909-VAN
REF-MICCAS-0909-STR
REF-BCAA50-0500-N/A
REF-MICWHE-0909-STR
REF-MICWHE-0909-VAN
REF-MICWHE-0909-CHIO
REF-MICWHE-0909-BAN
REF-1STOXT-2030-STR
REF-1STOXT-2030-VAN
REF-1STOXT-2030-CHO
REF-MUSBOM-0600-BCH
REF-MUSBOM-0600-FPU
REF-MUSBCF-0600-BCH
REF-MUSBCF-0600-FPU
REF-VEGANP-2100-STR
REF-VEGANP-2100-CHO
REF-INMPRO-2270-CPB
REF-DIETMR-2400-CPB
REF-INMPRO-2270-SCR
REF-INMPRO-2270-VIC
REF-MATRIX-1800-FRU
REF-INMPRO-2270-BOF
REF-MATRIX-1800-CHO
REF-INMPRO-2270-CHO
REF-ONESTO-2100-CHO
In the above list there are 2 skus which are:
REF-WHEREF-0001-TRO
REF-WHEREF-0001-ORA
The first 3 sets of characters split by - are the same. What would be the best approach of grouping all results leaving me an array something like this:
Array
(
[REF-WHEREF-0001] => Array
(
[0] => REF-WHEREF-0001-TRO
[1] => REF-WHEREF-0001-ORA
)
)
Are the first 3 groups (excluding the multiple -) always 13 characters? Then do something like this:
<?php
$arr = ["REF-MUSBOM-0500-ORA",
"REF-PROCOF-0001-LAT",
"REF-WHEREF-0001-TRO",
"REF-WHEREF-0001-PPL"];
$resultArr = [];
foreach ($arr as $sku) {
$resultArr[substr($sku, 0, 15)][] = $sku;
}
var_dump($resultArr);
If that length varies you might want to work with a regex or the strpos() of the third -.
I must say that I think you could come up with this yourself, since you were already thinking in the right direction i.e. foreach()
EDIT: Because I found other solutions more elegant looking, I decided to compare efficiency. This solution is a lot faster than the other ones.
I always create a new array with the index that I need for group, try this:
$arr=array('REF-MUSBOM-0500-ORA',
'REF-PROCOF-0001-LAT',
'REF-WHEREF-0001-TRO');
$newarr=array();
foreach($arr as $a){
$b=explode('-',$a);
array_pop($b);
$b=implode("-", $b);
$newarr[$b][]=$a;
}
echo '<pre>',print_r($newarr),'</pre>';
You will need to pick a group with some basics use of explode, implode and str_replace.
What does this solution do.
loop through the array of your items
explode to get last item index of exploded string assuming that it
would be dynamic in the end
implode & str_replace again to find out string of group name
And last strpos & in_array to have sample reponse
Solution
$array = array(
'REF-MUSBOM-0500-ORA',
'REF-PROCOF-0001-LAT',
'REF-WHEREF-0001-TRO',
'REF-WHEREF-0001-ORA',
'REF-SHAKER-0700-C/B',
'REF-CREMON-0100-N/A',
'REF-GLUSUL-0090-N/A',
'REF-CRECAP-0090-N/A',
'REF-ALBFER-0120-N/A',
);
$new_array = array();
foreach ($array as $key => $val) {
$group_arr = explode('-', $val);
$end = end($group_arr);
$combined_group = implode('-', $group_arr);
$group = str_replace('-' . $end, '', $combined_group);
if (strpos($val, $group) !== false && !in_array($group, $new_array)) {
$new_array[$group][] = $val;
}
}
echo '<pre>';print_r($new_array);echo '</pre>';
See demo on Sandbox

php substr_count on an array

How can you use substr_count to count each element in an array's occurance in another array?
i.e. $urls = array (
'www.thesun.co.uk',
'www.bbcnews.co.uk',
);
$names = array (
'rex kum',
'tony blair',
);
so if i wanted to use substr_count to count the occurance of the name rex kumi on the sun webpage, how would this work?
If you're going to do this a lot I'd put it in a function but:
foreach($names as $name)
{
foreach($urls as $url)
{
print "Count for $name and $url is: " . substr_count($url, $name);
}
}
The question that you asked (counting the instances of one array in another array) is different from what you actually asked (count the instances of one array, on a web site). You actually want a combination of my answer and the answer mentioned where you load the contents of the website. (Use nested foreach loops)
It looks you're missing the php basics, but what the hack. You'll use function nested foreach loop:
$results = array();
foreach( $urls as $url){
foreach( $names as $key => $name){
if( !isset( $results[$key])){
$results[$key] = 0; // you better initialize elements in separate foreach loop
}
// Strtolower because name may be capitalized, uppercased and so on
$content = strtolower( file_get_contents( $url));
$results[$key] += substr_count( $content, strtolower( $name));
}
}

PHP arrays & variable variables

With an array $s_filters that looks like this (many different keys possible):
Array
(
[genders] => m
[ages] => 11-12,13-15
)
How can I programatically convert this array to this:
$gender = array('m');
$ages = array('11-12','13-15');
So basically loop through $s_filters and create new arrays the names of which is the key and the values should explode on ",";
I tried using variable variables:
foreach( $s_filters as $key => $value )
{
$$key = array();
$$key[] = $value;
print_r($$key);
}
But this gives me cannot use [] for reading errors. Am I on the right track?
The following code takes a different approach on what you're trying to achieve. It first uses the extract function to convert the array to local variables, then loops though those new variables and explodes them:
extract($s_filters);
foreach(array_keys($s_filters) as $key)
{
${$key} = explode(",", ${$key});
}
$s_filters = Array
(
"genders" => "m",
"ages" => "11-12,13-15"
);
foreach($s_filters as $key=>$value)
{
${$key} = explode(',', $value);
}
header("Content-Type: text/plain");
print_r($genders);
print_r($ages);
$gender = $arr['gender'];
What you want there is unreadable, hard to debug, and overall a bad practice. It definitely can be handled better.

Categories