Reading array-like values from .INI file into PHP array? Example inside - php

I searched similar questions but found nothing quite did what I want.
I have a large INI file which contains basic key/value pairs on each line. Lots of the keys are basically "arrays" stored in .INI format as you'll see in the excerpt below:
# Excerpt from INI file itself...
CountryFlagsPackage=CountryFlags
bAllowBinds=False
bShowTime=False
Records[0]=14.64
Records[1]=16.33
Records[2]=11.47
Records[3]=13.26
Records[4]=16.64
Records[5]=19.34
I'm using parse_ini_string() to put the INI into an array which results in this:
# Excerpt from print_r() after parse_ini_string()
[CountryFlagsPackage] => CountryFlags
[bAllowBinds] => False
[bShowTime] => False
[Records[0]] => 14.64
[Records[1]] => 16.33
[Records[2]] => 11.47
[Records[3]] => 13.26
[Records[4]] => 16.64
[Records[5]] => 19.34
My question is: is there an elegant way to group all those "Records" entries into one PHP array? Currently - as you see above - they're just individual array items. Basically, I'm looking for the above array to become multi-dimensional.
I could use array_keys() and look for the text "Records" but that's not very elegant or re-usable.
Edit: I suppose I could use a regex to look for anything with square brackets at the end, too. Any better solutions?

I doubt there's a native way to do this, so here's what I did:
$file = parse_ini_string($ini);
foreach ($file as $key => $value) {
if (preg_match("/(\w+)\[\d+]/", $key, $matches)) {
// "Array" style key/value
$arrays[$matches[1]][] = $value;
} else {
// Standard key/value pair
$arrays[$key] = $value;
}
}
print_r($arrays);
Results in:
Array
(
[CountryFlagsPackage] => CountryFlags
[bAllowBinds] => False
[bShowTime] => False
[Records] => Array
(
[0] => 14.64
[1] => 16.33
[2] => 11.47
[3] => 13.26
[4] => 16.64
[5] => 19.34
)
)

Related

PHP arrays within an array - nested arrays PHP

I'm using ACF Pro plugin for Wordpress and use repeater fields.
With this code I get all the field values and additional info in an array:
$fields = get_field_object('slideshow');
With this code I can narrow it down to what I want to achieve:
print_r($fields[value];
By now I get this array below:
Array
(
[0] => Array
(
[videoWebm] => /wc/data/uploads/sea.webm
[videoMp4] => /wc/data/uploads/sea1.mp4
[text] => Test1
[kund] => Kund1
[link1] =>
[link2] =>
)
[1] => Array
(
[videoWebm] => /wc/data/uploads/turntable.webm
[videoMp4] => /wc/data/uploads/turntable.mp4
[text] => Test2
[kund] => Kund2
[link1] =>
[link2] =>
)
)
it can grow more - like [2] => Array, [3] => Array etc.
I want to access all videoWebm & videoMp4 values.
As of now I know how to access a specific value - for example:
print_r($fields[value][0][videoWebm]);
But I can't figure out how to access all of them and put them in two new arrays. One for videoWebm values and one for videoMp4 values. The problem for me is the index value when I try to loop thru the array. I don't know if this really is the way to go...
Anyone suggestions?
Best, Niklas
You can use foreach:
foreach ($fields[value] as $field) {
$videoWebms[] = $field['videoWebm']
$videoMp4s[] = $field['videoMp4'];
}
Or as splash58 said, use array_column:
$vieoWebms = array_column($fields[value], 'videoWebm');
$vieoMp4s = array_column($fields[value], 'videoMp4');
I would highly recommend you learn about php's foreach, it is very powerful and widely used (maybe a little too widely).
https://www.google.com/search?q=php%20foreach
To get the value from repeater use this :
$slides = get_field('slideshow');
if($slides){
foreach($slides as $slide){
echo $slide['videoWebm'];
echo $slide['text'];
echo $slide['kund]'];
echo $slide['link1'];
echo $slide['link2'];
}
}

PHP - Remove items from an array with given parameter

I've searched around and I found some similar questions asked, but none that really help me (as my PHP abilities aren't quite enough to figure it out). I'm thinking that my question will be simple enough to answer, as the similar questions I found were solved with one or two lines of code. So, here goes!
I have a bit of code that searches the contents of a given directory, and provides the files in an array. This specific directory only has .JPG image files named like this:
Shot01.jpg
Shot01_tn.jpg
so on and so forth. My array gives me the file names in a way where I can use the results directly in an tag to be displayed on a site I'm building. However, I'm having a little trouble as I want to limit my array to not return items if they contain "_tn", so I can use the thumbnail that links to the full size image. I had thought about just not having thumbnails and resizing the images to make the PHP easier for me to do, but that feels like giving up to me. So, does anyone know how I can do this? Here's the code that I have currently:
$path = 'featured/';
$newest = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::SKIP_DOTS));
$array = iterator_to_array($newest);
foreach($array as $fileObject):
$filelist = str_replace("_tn", "", $fileObject->getPathname());
echo $filelist . "<br>";
endforeach;
I attempted to use a str_replace(), but I now realize that I was completely wrong. This returns my array like this:
Array
(
[0] => featured/Shot01.jpg
[1] => featured/Shot01.jpg
[2] => featured/Shot02.jpg
[3] => featured/Shot02.jpg
[4] => featured/Shot03.jpg
[5] => featured/Shot03.jpg
)
I only have 3 images (with thumbnails) currently, but I will have more, so I'm also going to want to limit the results from the array to be a random 3 results. But, if that's too much to ask, I can figure that part out on my own I believe.
So there's no confusion, I want to completely remove the items from the array if they contain "_tn", so my array would look something like this:
Array
(
[0] => featured/Shot01.jpg
[2] => featured/Shot02.jpg
[4] => featured/Shot03.jpg
)
Thanks to anyone who can help!
<?php
function filtertn($var)
{
return(!strpos($var,'_tn'));
}
$array = Array(
[0] => featured/Shot01.jpg
[1] => featured/Shot01_tn.jpg
[2] => featured/Shot02.jpg
[3] => featured/Shot02_tn.jpg
[4] => featured/Shot03.jpg
[5] => featured/Shot03_tn.jpg
);
$filesarray=array_filter($array, "filtertn");
print_r($filesarray);
?>
Just use stripos() function to check if filename contains _tn string. If not, add to array.
Use this
<?php
$array = Array(
[0] => featured/Shot01.jpg
[1] => featured/Shot01_tn.jpg
[2] => featured/Shot02.jpg
[3] => featured/Shot02_tn.jpg
[4] => featured/Shot03.jpg
[5] => featured/Shot03_tn.jpg
)
foreach($array as $k=>$filename):
if(strpos($filename,"_tn")){
unset($array[$k]);
}
endforeach;
Prnt_r($array);
//OutPut will be you new array removed all name related _tn files
$array = Array(
[0] => featured/Shot01.jpg
[2] => featured/Shot02.jpg
[4] => featured/Shot03.jpg
)
?>
I can't understand what is the problem? Is it required to add "_tn" to array? Just check "_tn" existence and don't add this element to result array.
Try strpos() to know if filename contains string "_tn" or not.. if not then add filename to array
$path = 'featured/';
$newest = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::SKIP_DOTS));
$array = iterator_to_array($newest);
$filesarray = array();
foreach($array as $fileObject):
// Check - string contains "_tn" substring or not
if(!strpos($fileObject->getPathname(), "_tn")){
// Check - value already exists in array or not
if(!in_array($fileObject->getPathname(), $filesarray)){
$filesarray[] = $fileObject->getPathname();
}
}
endforeach;
print_r($filesarray);

http_build_query() dot is converted to underscore

Please check the below array:
Array([bunrey] => Array ([0] => 20130730181908615391000000)
[mt.shasta] => Array (
[0] => 20130708203742347410000000
[1] => 20130213201456984069000000
[2] => 20130712144459481348000000
)
[shingletwon] => Array
(
[0] => 20130801233842122771000000
)
)
I want to send this array as query string using http_build_query(),
I got the below string after using http_build_query():
bunrey%5B0%5D=20130730181908615391000000&mt.shasta%5B0%5D=20130708203742347410000000&mt.shasta%5B1%5D=20130213201456984069000000&mt.shasta%5B2%5D=20130712144459481348000000&shingletwon%5B0%5D=20130801233842122771000000
As you can see after sending this query string to some other file, there I am trying to retrieve. I had echoed the $_REQUEST object:
Array (
[bunrey] => Array
(
[0] => 20130730181908615391000000
)
[mt_shasta] => Array
(
[0] => 20130708203742347410000000
[1] => 20130213201456984069000000
[2] => 20130712144459481348000000
)
[shingletwon] => Array
(
[0] => 20130801233842122771000000
)
)
please check one of the key mr.shasta had changed to mr_shasta.
Can you people please provide any solution for this.
This is the standard PHP behaviour. Points are converted in underscores when used as array keys in a POST request.
From the documentation:
Dots and spaces in variable names are converted to underscores. For
example < input name="a.b" /> becomes $_REQUEST["a_b"].
The only solution is: stop using spaces and/or dots in array keys when using them in POST requests or, else, operate a string replace on every array key your receive.
$post = array();
foreach ($_POST as $key => $value)
$post[str_replace("_", ".", $key)] = $value;
Note that the code above would fix only the problem of . (converted to _) but not spaces. Also, if you have any _ in your original key this would be converted to . as well (as pointed out in the comments).
As you can see, the only real solution is to avoid . and spaces in $_POST keys. They just can't be received, not with PHP (and not with other server-side solutions that I know of): you'll loose that information.
No, this is not a limitation or a crap feature: this is a programming guideline. If you're using array keys names for something more than what you would normally do with a variable name, you're most likely doing something conceptually wrong (and I've done it many times too).
Just to give you an example on how wrong is that: in some programming solutions like asp.net-mvc (and, I think, codeigniter too) POST/GET requests are supposed to be mapped over functions in what's called a "controller". Which means that if you send a POST which looks like ["myKey" => "myValue", "myOtherKey" => "someValue"] you should then have a function which takes keys as arguments.
function(String myKey, String myOtherKey){ }
PHP have no default "on-top" framework (that I know of) which do this: it allows you to access $_POST directly. Cool: but this toy can breake easely. Use it with caution.
I may be wrong here, but I've replicated what you're doing and have found it depends how you assign the array as to whether or not it changes the key like this:
//doesn't change to mt_shasta
$array['bunrey'][0] = 20130730181908615391000000;
$array['bunrey']['mt.shasta'][0] = 20130708203742347410000000;
$array['bunrey']['mt.shasta'][1] = 20130708203742347410000000;
$array['bunrey']['mt.shasta'][2] = 20130708203742347410000000;
$array['bunrey']['shingletwon'][0] = 20130708203742347410000000;
//does change to mt_shasta
$array = array (
'0' => 20130730181908615391000000,
'mt.shasta' => array (
0 => 20130708203742347410000000,
1 => 20130213201456984069000000,
2 => 20130712144459481348000000,
),
'shingletwon' => array
(
0 => 20130801233842122771000000,
),
);

robust way to traverse an array

I had the data in XML file i.e.
<domain>
<host>xyz</host>
<key>keeeeeeeeeey</key>
</domain>
<domain>
<host>xyz</host>
<key>keeeeeeeeeey</key>
</domain>
From that xml I created an array for robustness had I knew how to find that using xml I would have done so but lack of my knowledge I converted that xml file into array using:
$json = json_encode($xml);
$array = json_decode($json,TRUE);`
Below is my array:
Array
(
[domain] => Array
(
[0] => Array
(
[host] => bdbdfbdvbdbdfbdfbf.net
[key] => 933f416350de1a955544b30b5bb7ca09cfa2311101a22972320cc4c7af2ecedc03f36b8a48961ef938972478592a1e261819052b51c09a45cf805663f83cb2c0233969255a2c3e2e7e212a295a247b785d41
)
[1] => Array
(
[host] => bdev1vvvvvvveinf.net
[key] => 933f416350de1a955544b30b5bb7ca09cfa2311101a22972320cc4c7af2ecedc03f36b8a48961ef938972478592a1e261819052b51c09a45cf805663f83cb2c0233969255a2c3e2e7e212a295a247b785d41
)
[2] => Array
(
[host] => bdev1.aaaaaaaaureinf.net
[key] => 933f416350de1a955544b30b5bb7ca09cfa2311101a22972320cc4c7af2ecedc03f36b8a48961ef938972478592a1e261819052b51c09a45cf805663f83cb2c0233969255a2c3e2e7e212a295a247b785d41
)
[3] => Array
(
[host] => bdennnnnnnninf.net
[key] => 933f416350de1a955544b30b5bb7ca09cfa2311101a22972320cc4c7af2ecedc03f36b8a48961ef938972478592a1e261819052b51c09a45cf805663f83cb2c0233969255a2c3e2e7e212a295a247b785d41
)
[4] => Array
(
[host] => bdeveewerwerwerwerreinf.net
[key] => 933f416350de1a955544b30b5bb7ca09cfa2311101a22972320cc4c7af2ecedc03f36b8a48961ef938972478592a1e261819052b51c09a45cf805663f83cb2c0233969255a2c3e2e7e212a295a247b785d41
)
)
)
I want a robust loop through which if I pass the host name it returns the key. Can anyone please throw some light? The size of the array could grow to 100 000 000 plus entries.
Change your array to look like:
$data = array('domain' => array(
'bdbdfbdvbdbdfbdfbf.net' => '933...',
'bdev1vvvvvvveinf.net' => '933...',
));
Then you can do this:
echo $data['domain']['bdbdfbdvbdbdfbdfbf.net'];
There is no "robust" way to do it with your current array. You'd have to search through the entire thing:
function get_key($data, $host)
{
foreach ($data['domain'] as $domain)
{
if ($domain['host'] == $host)
return $domain['key'];
}
}
Given this new information:
The size of the array could grow to 100 000 000 plus entries.
I retract the usefulness of this answer, as the entire concept of using any plain text format, including XML or a serialized PHP key-value array, to store this amount of data is just crazy.
You should store the data in a database with the domain indexed. Even an sqlite database would be a major upgrade from a linear probe of a text file.
Of course there are ways to store the data in a custom format that is optimized, but there's really no good reason to reinvent something a database can easily do.
If possible, I think it would be better if host could be in place of the array key instead of a numeric index. That means it could look like
Array
(
[domain] => Array
(
[bdbdfbdvbdbdfbdfbf.net] => Array
(
[key] => 933f416350de1a955544b30b5bb7ca09cfa2311101a22972320cc4c7af2ecedc03f36b8a48961ef938972478592a1e261819052b51c09a45cf805663f83cb2c0233969255a2c3e2e7e212a295a247b785d41
)
[bdev1vvvvvvveinf.net] => Array
(
[key] => 933f416350de1a955544b30b5bb7ca09cfa2311101a22972320cc4c7af2ecedc03f36b8a48961ef938972478592a1e261819052b51c09a45cf805663f83cb2c0233969255a2c3e2e7e212a295a247b785d41
)
[bdev1.aaaaaaaaureinf.net] => Array
(
[key] => 933f416350de1a955544b30b5bb7ca09cfa2311101a22972320cc4c7af2ecedc03f36b8a48961ef938972478592a1e261819052b51c09a45cf805663f83cb2c0233969255a2c3e2e7e212a295a247b785d41
)
)
)
which would be searchable with
$somedomain = "bdev1.aaaaaaaaureinf.net";
if (isset($domains['domain'][$somedomain])) {
// do stuff
//$domains['domain'][$somedomain]['key']; is the key you want
}
If you can, do it that way
Since you only need the [domain] array from the outer array, this should work
function getKey($domains)
{
foreach($domains as $domain)
{
if($domain['host'] == $testHost)
return $domain['key'];
}
return false;
}
$myKey = getKey($myArr['domain']);
Here is a method that works with the array that you gave. You don't have to make any changes to the array.
/**
* Find the Key of the Domain in the Array with a Given Host
* #param $given The host you want to search for
* #returns The key of the domain (of the array) that has the matching host
*/
function findHost($given)
{
// This code assumes that the data array is $array .
global $array;
foreach ($array["domain"] as $key => $value)
{
if ($value["host"] == $given)
return $key;
}
// If no matches
return false;
}
// Call findHost() as you desire.
// If there is no match, the function returns false.
// Otherwise, it returns the key of $array["domain"] that the host matches.
With 100 000 000 plus entries you're likely hitting the string length limit in PHP which would mean that you can't use json_encode and json_decode any longer.
This does something similar, but you need to metric yourself what's faster:
$array = (array) $xml;
array_walk_recursive($array, function(&$v) { $v = (array) $v; });
Good luck!
Anyway, I wonder how large that XML string is then. Hmm. I think the numbers you give are just not right, your question looks pretty bogus on a second thought.

PHP array issue

I have an Array List that I want to output like my example below. How can I achieve it in PHP?
Array List:
array(
[0] => First,
[1] => Second,
[2] => Third,
)
Want to output like this:
array(
[First] => First,
[Second] => Second,
[Third] => Third
)
Thanks,
steamboy
You can use array_combine() and pass two copies of your original array:
$new_list = array_combine($list, $list);
print_r($new_list);
Maps the contents of the first argument as keys and the contents of the second argument as values, in their defined order.
I haven't tested it, but this should work
foreach ($array as $key => $value) {
$array[$value] = $value;
unset($array[$key]);
}
That should do it
That is redundancy at its finest. It makes little sense to have keys matching their values, and probably highlights the need for a design change, or a potential optimisation somewhere in your application. Turning this:
array(
[0] => First,
[1] => Second,
[2] => Third,
)
into this:
array(
[First] => First,
[Second] => Second,
[Third] => Third
)
effectively reduces the amount of information you are storing, since you the developer know in advance that keys should match values.

Categories