So I am having issues understanding how to iterate over an array that looks as such in php:
$styles = array(
'css' => array(
'name' => array(
'core-css',
'bootstrap-css',
'bootstrap-responsive-css'
),
'path' => array(
get_bloginfo('stylesheet_url'),
get_template_directory_uri() . '/lib/bootstrap/css/bootstrap.min.css',
get_template_directory_uri() . '/lib/bootstrap/css/bootstrap.responsive.min.css'
),
),
);
Essentially this styles gets passed to a constructor of a class which then iterates over the array in a method that looks like this (note this array is stored class level in a protected value called _options, hence the $this->_options in the following code:
foreach ( $this->_options as $key => $value ) {
// load all the css files
if (isset ( $this->_options ['css'] )) {
foreach ( $value ['name'] as $name ) {
foreach ( $value ['path'] as $path ) {
wp_enqueue_style ( $name, $path );
}
}
}
}
This will spit out something like:
core-css style.css
core-css bootstrap
core-css bootstrap-responsive
.
The problem should be clear right now, the name never changes and I think it has something to do with how I am iterating over the array of, essentially, arrays.
So your help is much appreciated.
The path array is not apart of the name array, and should look something like:
foreach ( $this->_options as $key => $value ) {
// load all the css files
if (isset ( $this->_options ['css'] )) {
foreach ( $value ['path'] as $k=>$path ) {
wp_enqueue_style ( $value['name'][$k], $path );
}
}
}
Or, you could always change the structure of your array:
$styles = array(
'css' => array(
array(
'name'=>'core-css',
'path'=>get_bloginfo('stylesheet_url')
),
array(
'name'=>'bootstrap-css',
'path'=>get_template_directory_uri() . '/lib/bootstrap/css/bootstrap.min.css'
),
array(
'name'=>'bootstrap-responsive-css',
'path'=>get_template_directory_uri() . '/lib/bootstrap/css/bootstrap.responsive.min.css'
)
)
);
foreach($this->_options as $key => $value){
if (isset ( $this->_options ['css'] )) {
foreach($this->_options ['css'] as $k=>$v){
wp_enqueue_style ( $v['name'], $v['path'] );
}
}
}
Hope that order matches, other way you in trouble.
Something like this:
if (isset($this->_options['css'])) {
foreach ($this->_options['css']['name'] as $key => $name) {
echo $name; // Your name
echo $this->_options['css']['path'][$key]; // Your math
}
}
Related
I have created an array of values and i'm wondering whether its possible to get the value of the parent item.
For example, if I have the value logo how can I retrieve that it belongs to FREE?
$widget_classes = array(
'FREE' => array(
'logo',
'clock',
'text',
'rss',
'rss marquee',
),
);
Iterate over your array considering keys, as FREE is the key:
foreach ($widget_classes as $key => $class) {
if (in_array('logo', $class)) {
echo $key;
}
}
Here's a oneliner, make sure you understand what's going on here and how many iterations over arrays are performed:
echo array_keys(array_filter($widget_classes, function($v) { return in_array('logo', $v); }))[0];
If your array becomes multidimensional like below then recursive function will help to find the parent of the value, but it will return the first matching.
<?php
$widget_classes = array(
'FREE' => array(
'logo' => [
'pogo',
'bunny' => [ 'rabbit' ]
],
'clock',
'text',
'rss',
'rss marquee',
),
);
$parent = recursiveFind( $widget_classes, 'rabbit');
var_dump( $parent );
function recursiveFind(array $array, $needle) {
foreach ($array as $key => $value) {
if( is_array( $value ) ){
$parent = recursiveFind( $value, $needle );
if( $parent === true ){
return $key;
}
}elseif ( $value === $needle ) {
return true;
}
}
return isset( $parent ) ? $parent : false;
}
?>
I have an array of files with dependencies. I need them sorted so all dependent files are indexed after their dependency. I've made a lot of attempts with forEach loops, while loops, but once a dependency is moved, the loops don't account for previous iterations and indexed elements wind up out of order.
I have a simplified version of the data I am working with:
$dependencies = array(
array(
'handle' => 'jquery',
'requires' => array(
'jquery-core',
'jquery-migrate'
)
),
array(
'handle' => 'jquery-migrate',
'requires' => array()
),
array(
'handle' => 'common',
'requires' => array(
'utils',
'jquery',
'jquery-core',
'jquery-migrate',
'jquery-effects-core',
'backbone'
)
),
array(
'handle' => 'jquery-effects-core',
'requires' => array(
'jquery',
'jquery-core',
'jquery-migrate'
)
),
array(
'handle' => 'backbone',
'requires' => array(
'underscore',
'jquery'
)
),
array(
'handle' => 'underscore',
'requires' => array()
),
array(
'handle' => 'utils',
'requires' => array()
),
array(
'handle' => 'jquery-core',
'requires' => array()
)
);
If [handle] appears in an elements [requires] array, that element needs to be moved ahead of the indicated [requires] element, all while maintaining any other dependencies previously accounted for.
function moveEle(&$array, $a, $b){
$out = array_splice($array, $a, 1);
array_splice($array, $b, 0, $out);
}
foreach($dependencies as $i=>$dependency){
if( count($dependency['requires'])>0 ){
$itr = count($dependency['requires']);
echo $dependency['handle']."<br/>";
while($itr > 0){
// loop through current files required files
foreach( $dependency['requires'] as $k=>$dep ){
// loop through dependencies array again to find required file handle
echo "-- " . $dep . "<br/>";
foreach($dependencies as $j=>$jDep){
// $j = index in dependencies array of required file, $i = index in dependencies array of dependent file.
if( $dep === $jDep['handle'] && $j > $i ){
echo "found " . $jDep['handle'] . "# " . $j."<br/>";
moveEle(&$dependencies, $j, $i );
}
}
$itr--;
}
}
}
}
I'm taking it there is probably some recursive way to do this that is a little beyond my scope of skill at this point. Any help would be greatly appreciated.
I did find this solution:
PHP Order array based on elements dependency
which does work, however, once the array gets to 150 files (the actual data size), it times out or takes an incredibly long time. I'd like a more efficient solution, if one exists.
Well, I got the desired results with this:
/*
*
* #description return nested array with all dependencies & sub dependencies
*
**/
function getWithDependencies($dependency, $collection){
$helper = new Insight_WP_Scripts_Helpers();
$set = array(
'handle' => $dependency,
'dependencies' => array()
);
foreach($collection as $index=>$data){
if( $data['handle'] === $set['handle'] ){
// echo "<h4>".$data['handle']."</h4>";
if(count($helper->getDependencies($set, $collection))>0){
$dependencies = $helper->getDependencies($set['handle'], $collection);
foreach($dependencies as $i=>$dependency){
// echo $dependency . "<br/>";
$set['dependencies'][$i] = array(
'handle' => $dependency,
'dependencies' => array()
);
if( count($helper->getDependencies($dependency, $collection)) > 0 ){
foreach(getWithDependencies($dependency, $collection) as $k=>$dep){
$set['dependencies'][$i]['dependencies'] = $dep;
}
}
}
}
}
}
return $set;
}
/*
*
* #description recursively sorts dependencies to depth returned by getWithDependencies()
*
**/
function sortDependency($data,&$collection){
$helper = new Insight_WP_Scripts_Helpers();
foreach($collection as $index=>$inst){
if( $inst['handle'] === $data['handle'] && count($data['dependencies'])>0){
// iterate over each dependency
foreach( $inst['dependencies'] as $i=>$dependency ){
// iterate over the collection to find dependencies position for comparison against dependent file.
foreach( $collection as $k=>$kdep ){
if($kdep['handle'] === $dependency['handle'] && $index < $k){
$helper->moveArrayElement($collection, $k, $index);
// call recursively to search full depth
if( count($dependency['dependencies']) > 0 ){
sortDependency($dependency,$collection);
}
}
}
}
}
}
}
foreach( $dependencies as $index=>$data ){
$fullDependencies = array();
foreach($dependencies as $i=>$dependency){
$fullDependencies[] = getWithDependencies($dependency['handle'], $dependencies);
}
}
$_fullDependencies = $fullDependencies;
foreach( $fullDependencies as $index=>$data ){
sortDependency($data,$_fullDependencies);
}
$fullDependencies = $_fullDependencies;
return $fullDependencies;
This is my simple looper code
foreach( $cloud as $item ) {
if ($item['tagname'] == 'nicetag') {
echo $item['tagname'];
foreach( $cloud as $item ) {
echo $item['desc'].'-'.$item['date'];
}
} else
//...
}
I need to use if method in this looper to get tags with same names but diferent descriptions and dates. The problem is that I dont know every tag name becouse any user is allowed to create this tags.
Im not really php developer so I'm sory if it's to dummies question and thanks for any answers!
One possible solution is to declare a temporary variable that will hold tagname that is currently looped through:
$currentTagName = '';
foreach( $cloud as $item ) {
if ($item['tagname'] != $currentTagName) {
echo $item['tagname'];
$currentTagName = $item['tagname'];
}
echo $item['desc'] . '-' . $item['date'];
}
I presume that your array structure is as follows:
$cloud array(
array('tagname' => 'tag', 'desc' => 'the_desc', 'date' => 'the_date'),
array('tagname' => 'tag', 'desc' => 'the_desc_2', 'date' => 'the_date_2'),
...
);
BUT
This solution raises a problem - if your array is not sorted by a tagname, you might get duplicate tagnames.
So the better solution would be to redefine your array structure like this:
$cloud array(
'tagname' => array (
array('desc' => 'the_desc', 'date' => 'the_date'),
array('desc' => 'the_desc_2', 'date' => 'the_date_2')
),
'another_tagname' => array (
array('desc' => 'the_desc_3', 'date' => 'the_date_3'),
...
)
);
and then you can get the data like this:
foreach ($cloud as $tagname => $items) {
echo $tagname;
foreach($items as $item) {
echo $item['desc'] . '-' . $item['date'];
}
}
So I have this $_POST which I am trying to check if it is set but when I do that, it gives me the error in the title.
The $_POST contains array within array. So that could be the reason. $_POST has value if the checkbox is checked otherwise nothing is posted.
So example of what $_POST would contain:
array() => 'item-one' => array( 102 ) => 'on'
I am using this in PHP:
function testing( $db_id ) {
$fields = array( 'one', 'two' );
foreach( $fields as $field ) {
if ( isset( $_POST['item-' . $field][$db_id] ) ) {
// do something
}
}
}
Thanks for looking.
Try this,
foreach( $fields as $field ) {
if (isset($_POST['item-'.$field]) and in_array($db_id,$_POST['item-'.$field])){
// do something
}
}
Alternatively you can try it like,
$fields=array('item-one','item-two')
foreach( $fields as $key=>$field ) {
if (isset($_POST[$field]) and in_array($db_id,$_POST[$field])){
// do something
}
}
Try with in_array:
$fields = array( 'one', 'two' );
foreach( $fields as $field ) {
if ( in_array($_POST['item-' . $field][$db_id], $fields) ) {
// do something
}
}
I need to read nested arrays without knowing how the array will look.
For example;
$data = array(
'Data1_lvl1' => array(
'Data1_lvl2' => "value",
'Data2_lvl2' => array(
'Data1_lvl3' => "value"
)
),
'Data2_lvl1' => 'value'
);
Needs to be formatted to strings like:
Data1_lvl1/Data1_lvl2/
Data1_lvl1/Data2_lvl2/Data1_lvl3/
Data2_lvl1/
But the array can be of any size with any number of nested arrays inside it.
$data = array(
'Data1_lvl1' => array(
'Data1_lvl2' => "value",
'Data2_lvl2' => array(
'Data1_lvl3' => "value"
)
),
'Data2_lvl1' => 'value'
);
function printArray($array)
{
foreach ($array as $key=>$value)
{
echo $key.'/';
if (is_array($value))
{
printArray($value);
} else {
echo '<br>';
}
}
}
printArray($data);
If you want to output only the name of array elements then this recursive function will do the trick.
Your data:
$data = array(
'Data1_lvl1' => array(
'Data1_lvl2' => "value",
'Data2_lvl2' => array(
'Data1_lvl3' => "value"
)
),
'Data2_lvl1' => 'value'
);
Function:
function array2str($array, $str) {
foreach($array as $key => $val) {
if (is_array($val) ) {
$str .= $key . '/';
array2str($val, $str);
}
}
echo $str.'<br />';
return $str;
}
array2str($data);
As you can see the script does ECHO in itself with <br /> to break the line when viewing results in a browser.
One way would to walk recursively through array with function similar to this:
<?php
function f($d, $str = '') {
foreach ($d as $key => $val) {
if (is_array($val)) f($val, $str . '/' . $key); // If this element is array parse next level
else print_r($str . '/' . $key . '/'); // Output current string or do what you need to do with it..
}
}
$data = array(
'Data1_lvl1' => array(
'Data1_lvl2' => "value",
'Data2_lvl2' => array(
'Data1_lvl3' => "value"
)
),
'Data2_lvl1' => 'value'
);
f($data);
with that function:
<?php
function print_tree ($data, $prefix = '', &$index = 1) {
foreach($data as $key => $datum) {
echo $index++ . '. ' . ($new_prefix = $prefix . $key . '/') . PHP_EOL;
if (is_array($datum)) {
print_tree ($datum, $new_prefix, $index);
}
}
}
I get
Data1_lvl1/
Data1_lvl1/Data1_lvl2/
Data1_lvl1/Data2_lvl2/
Data1_lvl1/Data2_lvl2/Data1_lvl3/
Data2_lvl1/