Iterating over array of arrays and presenting the results - php

How can I access the contents of $value[$i] which is an array. No luck using foreach in the form below.
The idea is to loop through $contentArray and display one item from each sub-array on every iteration.
$addsContent = $Adds->selectAdds(10);
$sharedArticlesContent = $SharedContent->getSharedContent($topic_selected, $filter_selected);
$blogPostsContent = $BlogPosts->getRecentBlogPostsByTopic("business");
$contentArray = array(
$sharedArticlesContent,
$addsContent ,
$blogPostsContent
);
foreach($contentArray as $value)
{
if(count($value)>$maxLength)
{
$maxLength = count($value);
}
}
for($i=0; $i<$maxLength; $i++)
{
foreach($contentArray as $value)
{
if(isset($value[$i]))
{
if($value==$sharedArticlesContent){
$data = $value[$i];
foreach($sharedArticlesContent as $data){
$post_id = $data['id'];
$uploaded_by = $data['uploaded_by'];
$text = $data['text'];
$image = $data['image'];
require 'template1.php';
}
}elseif($value==$addsContent){
//template2
}else{
//template3
}
}
}
}

You're dealing with an associative array here, you can access it like that:
<?php
$addsContent = $Adds->selectAdds(10);
$sharedArticlesContent = $SharedContent->getSharedContent($topic_selected, $filter_selected);
$blogPostsContent = $BlogPosts->getRecentBlogPostsByTopic("business");
$contentArray = array(
$sharedArticlesContent,
$addsContent ,
$blogPostsContent
);
foreach($contentArray as $value)
{
if(count($value)>$maxLength)
{
$maxLength = count($value);
}
}
for($i=0; $i<$maxLength; $i++)
{
foreach($contentArray as $value)
{
if(isset($value[$i]))
{
if($value==$sharedArticlesContent)
{
$post_id = $value[$i]['id'];
$uploaded_by = $value[$i]['uploaded_by'];
$text = $value[$i]['text'];
$image = $value[$i]['image'];
require 'template1.php';
}
elseif($value==$addsContent)
{
//template2
}
else
{
//template3
}
}
}
}

You don't need the foreach. $data is an associative array, you don't need to loop through it.
if($value==$sharedArticlesContent){
$data = $value[$i];
$post_id = $data['id'];
$uploaded_by = $data['uploaded_by'];
$text = $data['text'];
$image = $data['image'];
require 'template1.php';
}

Related

Error while uploading multiple images for a product in Laravel

Im receiving this error, "foreach() argument must be of type array|object, null given" but with a successful upload, how can resolve it.
foreach ($this->attribute_values as $key=>$attribute_value) {
$avalues = explode(",", $attribute_value);
foreach ($avalues as $avalue) {
$attr_value = new AttributeValue();
$attr_value->product_attribute_id = $key;
$attr_value->value = $avalue;
$attr_value->product_id = $product->id;
$attr_value->save();
}
}
Well I wrapped the code in an if statement like this.
if (is_array($this->attribute_values)){
foreach ($this->attribute_values as $key => $attribute_value) {
$avalues = explode(",", $attribute_value);
foreach ($avalues as $avalue) {
$attr_value = new AttributeValue();
$attr_value->product_attribute_id = $key;
$attr_value->value = $avalue;
$attr_value->product_id = $product->id;
$attr_value->save();
}
}
}
if (is_array($this->attribute_values)) {
$attr_values = [];
foreach ($this->attribute_values as $key => $attribute_value) {
$avalues = explode(",", $attribute_value);
if (is_array($avalues)) {
foreach ($avalues as $avalue) {
$attr_values['product_attribute_id'] = $key;
$attr_values['value'] = $avalue;
$attr_value['product_id'] = $product->id;
}
AttributeValue::insert($attr_values);
}
}
}
$main_data = new Collection($this->attribute_values);
$main_data = $main_data->toArray();
foreach ($main_data as $key=>$attribute_value) {
$avalues = explode(",", $attribute_value);
foreach ($avalues as $avalue) {
$attr_value = new AttributeValue();
$attr_value->product_attribute_id = $key;
$attr_value->value = $avalue;
//$attr_value->product_id = $product->id;
$attr_value->save();
}
}

Loop through array of arrays and display each sub-array in sequence

I have an array which contains 3 different arrays.
$arrayAll = (
0 => $array1,
1 => $array2,
2 => $array3
);
How can I loop through $arrayAll, displaying the first element of each sub-array(array1,array2,array3) on each itteration?
So, the output will be:
$array1[0],$array2[0],$array3[0],
$array1[1],$array2[1],$array3[1],
$array1[2],$array2[2],$array3[2]
and so on.. until all sublements are fetched.
EDIT:
$addsContent = $Adds->selectAdds(10);
$sharedArticlesContent = $SharedContent->getSharedContent($topic_selected, $filter_selected);
$blogPostsContent = $BlogPosts->getRecentBlogPostsByTopic("business");
$contentArray = array(
$sharedArticlesContent,
$addsContent ,
$blogPostsContent
);
foreach($contentArray as $value)
{
if(count($value)>$maxLength)
{
$maxLength = count($value);
}
}
for($i=0; $i<$maxLength; $i++)
{
foreach($contentArray as $value)
{
if(isset($value[$i]))
{
if($value==$sharedArticlesContent){
$data = $value[$i];
foreach($sharedArticlesContent as $data){
$post_id = $data['id'];
$uploaded_by = $data['uploaded_by'];
$text = $data['text'];
$image = $data['image'];
require 'template1.php';
}
}elseif($value==$addsContent){
//template2
}else{
//template3
}
}
}
}
$maxLength = 0;
foreach($arrayAll as $value)
{
if(count($value)>$maxLength)
{
$maxLength = count($value);
}
}
for($i=0; $i<$maxLength; $i++)
{
foreach($arrayAll as $value)
{
if(isset($value[$i]))
{
echo $value[$i];
}
}
}

How do I put this array into csv or excel?

I can't figure out a way to do this and I really bad with working with arrays so I hope someone can help me.
I have array $stuck that just contains names, like this
$stuck = array('Daniel','Alex','alfredo','dina');
I am using sort to put the names in alphabetical order, like this
sort($stuck);
Now the thing is I want to put this array into a csv or excel file so the first letter of name will be the title and all the names with this letter will be under this title.
This is an example of what I am trying to accomplish
Here try this. I added comments between the code.
$csvArray = array();
$nameArray = array('Daniel','Alex','alfredo','dina');
//Create an array that can be used for creating the CSV
foreach($nameArray as $name)
{
$firstLetter = strtoupper(substr($name, 0,1));
$csvArray[$firstLetter][] = $name;
}
//Determine the subarray which have the must rules
$maxRuleCount = 0;
foreach($csvArray as $firstLetter => $nameArray)
{
if(count($nameArray) > $maxRuleCount)
{
$maxRuleCount = count($nameArray);
}
}
//Create the first rule (letters)
$csvContent = implode(';', array_keys($csvArray));
$csvContent .= "\r\n";
//Loop through the CSV array and create rules of the names
for($i = 0 ; $i < $maxRuleCount ; $i++)
{
foreach($csvArray as $firstLetter => $nameArray)
{
$csvContent .= #$csvArray[$firstLetter][$i].';';
}
$csvContent .= "\r\n";
}
//The hole csv content is in the $csvContent variable now
//If you want to print it you need to add the text/plain header because of the \r\n new line characters
header("Content-Type:text/plain");
echo $csvContent;
Ouput is:
D;A
Daniel;Alex;
dina;alfredo;
<?php
$stuck = array('Daniel','Alex','Dina','durban','eigor','alfredo','dina');
// associate names with first letters in a new array
foreach ($stuck as $name) {
$first_letter = strtoupper( substr( $name, 0, 1 ) );
$new_name_array[ $first_letter ][] = $name;
}
// store the first letter list in an array and sort it
$first_letters = array_keys( $new_name_array );
sort( $first_letters );
// sort the name lists
foreach( array_keys( $new_name_array ) as $letter ) {
sort( $new_name_array[$letter] );
}
// output csv header row
echo "'".implode( "','", $first_letters )."'\n";
// output the CSV name rows
$i = 0;
while ( true ) {
$row = array();
$is_row = false;
foreach( $first_letters as $letter ) {
$row[] = $new_name_array[ $letter ][ $i ];
if( ! empty( $new_name_array[ $letter ][ $i ] ) ) $is_row = true;
}
if( ! $is_row ) exit;
echo "'" . implode( "','", $row ) . "'\n";
$i++;
}
?>
Outputs quoted CSV:
'A','D','E'
'Alex','Daniel','eigor'
'alfredo','Dina',''
'','dina',''
'','durban',''
<?php
$stuck = array('Daniel','Alex','alfredo','dina', 'eigor', 'durban');
sort($stuck);
$sortedNames = array();
$maxEl = 0;
foreach ($stuck as $name) {
$name = strtolower($name);
$sortedNames[$name{0}][] = $name;
$maxEl = count($sortedNames[$name{0}]) < $maxEl ? $maxEl : count($sortedNames[$name{0}]);
}
$headers = array_keys($sortedNames);
$finalArray = array($headers);
for($i = 0; $i < $maxEl; $i++) {
$tmpRow = array();
foreach ($sortedNames as $names) {
$tmpRow[] = isset($names[$i]) ? $names[$i] : '';
}
$finalArray[] = $tmpRow;
}
$file = fopen("names.csv","w");
foreach ($finalArray as $line)
{
fputcsv($file,$line);
}
fclose($file);
Here is my attempt at this question:
$names = array('Daniel','Alex','alfredo','dina', 'eigor', 'falfoul', 'fiona');
natcasesort($names);
$columns = array();
foreach ($names as $name) {
$first = strtoupper(substr($name, 0, 1));
$columns[$first][] = $name;
}
// pad the columns so they all have the same number of rows
$maxRows = 0;
foreach ($columns as &$col) {
$numRows = count($col);
if ( $numRows > $maxRows) {
$maxRows = $numRows;
}
}
// pad the columns
foreach ($columns as &$column) {
$column = array_pad($column, $maxRows, '');
}
$firstLetter = array_keys($columns);
$numCols = count($firstLetter);
// transpose the columns array
$rows = array();
foreach ($columns as $csvCol) {
foreach ($csvCol as $k=>$n) {
$rows[$k][] = $n;
}
}
// pad the rows to ensure they all have the same number of
// columns
foreach ($rows as &$row) {
$row = array_pad($row, $numCols, '');
}
// add the title row to the rows
array_unshift($rows, $firstLetter);
$handle = fopen("names.csv", 'w');
foreach ($rows as $fRow) {
fputcsv($handle, $fRow);
}

Remove empty array elements from the $_FILES array

I have a photo album, with a 'photos' field in database which has serialized data and is base 64 encoded. I can upload up to 21 photos at the same time for the album (multiple uploading). When trying to add new photos to the album on edit mode, I can't get the new $_FILES array to merge with the old array in the database. I want to update only the values that I have changed. So let's say I already had 2 images inside my album, I would like to add a 3rd image without losing the other 2 images. I know I need to use unset() to delete empty values but I think i'm not doing it correctly. Here's my code:
if (isset($_REQUEST['action']) && $_REQUEST['action'] == 'edit') {
//select photo album and get photos and descriptions to be merged with new.
$album_id = $_REQUEST['album_id'];
$old_photos = null;
$old_descriptions = null;
$getAlbumQ = mysql_query("select * from albums where id='$album_id'");
while ($old_album = mysql_fetch_array($getAlbumQ)) {
$old_photos = unserialize(base64_decode($old_album['photos']));
$old_descriptions = unserialize(base64_decode($old_album['descriptions']));
}
if (isset($_POST['album_name']) && isset($_POST['desc'])) {
$name = $_POST['album_name'];
$desc = $_POST['desc'];
$idesc = array();
$target_path = "../uploads/albums/";
foreach ($_FILES as $k => $v) {
//first upload photos
$path = $target_path . basename($v['name']);
if(move_uploaded_file($v['tmp_name'], $path)) {
$hasUpload = true;
}
}
for ($j = 1; $j < 21; $j++) {
$img_index = $j;
$img_desc = $_POST['desc_' . $img_index];
$asdf = $_FILES['image_' . $img_index]['name'];
array_push($idesc, $img_desc);
}
foreach( $_FILES['images']['name'] as $key => $value ) {
if( empty($value) ) {
unset( $_FILES['images']['name'][$key] );
}
}
for ($i = 1; $i < 21; $i++) {
if($_FILES['image_'.$i]['name']!= '')
{
$hasUpload = true;
$presults = array_merge($old_photos, $_FILES); //THE PROBLEM WITH MERGING ARRAYS OCCURS HERE
$dresults = array_merge($old_descriptions, $idesc);
$images = base64_encode(serialize($presults));
$descriptions = base64_encode(serialize($dresults));
$posted = date("Y-m-d H:i:s");
}
else {
$hasUpload = false;
$presults = $old_photos;
$dresults = $idesc;
$images = base64_encode(serialize($presults));
$descriptions = base64_encode(serialize($dresults));
$posted = date("Y-m-d H:i:s");
}
}
}
}
I tried something similar to what Muu suggested. Combined it with another piece of code of a custom merge function found here http://keithdevens.com/weblog/archive/2003/Mar/30/MergeTwoArrays and it worked fine! Thanks for your help
Just needed to add the following lines of code outside the for ($i = 1; $i < 21; $i++) loop:
//delete empty values for $_FILES array
foreach ($_FILES as $key => $value) {
foreach ($value as $k => $v) {
if ($k=='name' && $v!='') {
break;
} else {
unset($_FILES[$key]);
}
}
}
//custom array merge function
function merge(&$a, &$b){
$keys = array_keys($a);
foreach($keys as $key){
if(isset($b[$key])){
if(is_array($a[$key]) and is_array($b[$key])){
merge($a[$key],$b[$key]);
}else{
$a[$key] = $b[$key];
}
}
}
$keys = array_keys($b);
foreach($keys as $key){
if(!isset($a[$key])){
$a[$key] = $b[$key];
}
}
}
then instead of array_merge(), I used merge() inside the for ($i = 1; $i < 21; $i++) loop:
$presults = merge($old_photos, $_FILES);
Instead of removing the empty values from the array, why not just ignore them?
For example:
$nonEmptyArray = array();
foreach ($_FILES as $k => $v) {
if (!$v) {
continue;
}
$nonEmptyArray[$k] = $v;
}
$_FILES = $nonEmptyArray;

Build Array Tree from URLs

I need to build an tree (with arrays) from given urls.
I have the following list of urls:
http://domain.com/a/a.jsp
http://domain.com/a/b/a.jsp
http://domain.com/a/b/b.jsp
http://domain.com/a/b/c.jsp
http://domain.com/a/c/1.jsp
http://domain.com/a/d/2.jsp
http://domain.com/a/d/a/2.jsp
now i need an array like this:
domain.com
a
a.jsp
b
a.jsp
b.jsp
c.jsp
c
1.jsp
d
2.jsp
a
2.jsp
How can i do this with php?
i thought mark's solution was a bit complicated so here's my take on it:
(note: when you get to the filename part of the URI, I set it as both the key and the value, wasn't sure what was expected there, the nested sample didn't give much insight.)
<?php
$urls = array(
'http://domain.com/a/a.jsp',
'http://domain.com/a/b/a.jsp',
'http://domain.com/a/b/b.jsp',
'http://domain.com/a/b/c.jsp',
'http://domain.com/a/c/1.jsp',
'http://domain.com/a/d/2.jsp',
'http://domain.com/a/d/a/2.jsp'
);
$array = array();
foreach ($urls as $url)
{
$url = str_replace('http://', '', $url);
$parts = explode('/', $url);
krsort($parts);
$line_array = null;
$part_count = count($parts);
foreach ($parts as $key => $value)
{
if ($line_array == null)
{
$line_array = array($value => $value);
}
else
{
$temp_array = $line_array;
$line_array = array($value => $temp_array);
}
}
$array = array_merge_recursive($array, $line_array);
}
print_r($array);
?>
$urlArray = array( 'http://domain.com/a/a.jsp',
'http://domain.com/a/b/a.jsp',
'http://domain.com/a/b/b.jsp',
'http://domain.com/a/b/c.jsp',
'http://domain.com/a/c/1.jsp',
'http://domain.com/a/d/2.jsp',
'http://domain.com/a/d/a/2.jsp'
);
function testMapping($tree,$level,$value) {
foreach($tree['value'] as $k => $val) {
if (($val == $value) && ($tree['level'][$k] == $level)) {
return true;
}
}
return false;
}
$tree = array();
$i = 0;
foreach($urlArray as $url) {
$parsed = parse_url($url);
if ((!isset($tree['value'])) || (!in_array($parsed['host'],$tree['value']))) {
$tree['value'][$i] = $parsed['host'];
$tree['level'][$i++] = 0;
}
$path = explode('/',$parsed['path']);
array_shift($path);
$level = 1;
foreach($path as $k => $node) {
if (!testMapping($tree,$k+1,$node)) {
$tree['value'][$i] = $node;
$tree['level'][$i++] = $level;
}
$level++;
}
}
echo '<pre>';
for ($i = 0; $i < count($tree['value']); $i++) {
echo str_repeat(' ',$tree['level'][$i]*2);
echo $tree['value'][$i];
echo '<br />';
}
echo '</pre>';

Categories