Jump to content

Adding elements from one multidimensional array to another


Recommended Posts

Suppose I have 2 arrays like the two below.  I want to change each element of the first array.  I want to add  [‘person_id’] => 3 to each element and I want to add the [name] element from each element of the second array to each element of the first, with the [name] value corresponding. i.e.  [name] from the first element in array 2 added to the first element of array one, [name] from the second element of array two added to the second element of array one, and[name] from the third element of array two added to the third element of array one.  The element can be called "name" in each element of the first array.

Thus the person_id would be the same in all elements of array one and the name element from array two would be added, changing for each element.

It’s kind of a foreach in a foreach and I couldn’t figure out how to do it.  array_walk might be useful as well though I couldn’t figure that our either.

What’s happening here is that I am uploading three image files and want to insert the information about each file into corresponding file fields in a row determined by the person_id, extracting the image filenames from array 2.

Thanks for help with this,

—Kenoli

 Array 1
(
    [person_id] => 3
    [1] => Array
        (
            ['title'] => qwerqwer
            ['medium'] => dfsadfasda
        )

    [2] => Array
        (
            ['title'] => sadfasdfad
            ['medium'] => Asdfsadf
        )

    [3] => Array
        (
            ['title'] => asdfsadf
            ['medium'] => Sadfsedf
        )

    [submit] => Submit
)

Array 2
(
    [image1] => Array
        (
            [name] => _DSC0080.jpg
            [type] => image/jpeg
            [tmp_name] => /Applications/XAMPP/xamppfiles/temp/phpxY22EN
            [error] => 0
            [size] => 1784656
        )

    [image2] => Array
        (
            [name] => _DSC0030.jpg
            [type] => image/jpeg
            [tmp_name] => /Applications/XAMPP/xamppfiles/temp/phpy2Wq43
            [error] => 0
            [size] => 1724811
        )

    [image3] => Array
        (
            [name] => _DSC0001.jpg
            [type] => image/jpeg
            [tmp_name] => /Applications/XAMPP/xamppfiles/temp/phpZSBkAp
            [error] => 0
            [size] => 2278345
        )

)

 

Link to post
Share on other sites

Think of it this way:

Array1 (I'll call 'titles') is the destination array.  It is static as defined, and you will update it based on the contents of Array2 (which I'll call 'images').

You do not need nested foreach statements here, only a foreach through the images array.

// Get the person_id
$person_id = $titles['person_id'];

//Loop through images
$index = 1;
foreach ($images as $image) {
    $titles[$index]['person_id'] = $person_id;
    $titles[$index]['name'] = $image['name'];
    $index++;
}

 

This code is susceptible to issues with the structures you provided.  Here is some testable code:

 

$titles = array(
    'person_id' => 3,
    1 => Array
        (
            'title' => 'qwerqwer',
            'medium' => 'dfsadfasda'
        ),

    2 => Array
        (
            'title' => 'sadfasdfad',
            'medium' => 'Asdfsadf'
        ),

    3 => Array
        (
            'title' => 'asdfsadf',
            'medium' => 'Sadfsedf'
        ),

    'submit' => 'Submit'
);

$images = array(
    'image1' => Array
        (
            'name' => '_DSC0080.jpg',
            'type' => 'image/jpeg',
            'tmp_name' => '/Applications/XAMPP/xamppfiles/temp/phpxY22EN',
            'error' => 0,
            'size' => 1784656
        ),

    'image2' => Array
        (
            'name' => '_DSC0030.jpg',
            'type' => 'image/jpeg',
            'tmp_name' => '/Applications/XAMPP/xamppfiles/temp/phpy2Wq43',
            'error' => 0,
            'size' => 1724811
        ),

    'image3' => Array
        (
            'name' => '_DSC0001.jpg',
            'type' => 'image/jpeg',
            'tmp_name' => '/Applications/XAMPP/xamppfiles/temp/phpZSBkAp',
            'error' => 0,
            'size' => 2278345
        )

);

// Get the person_id
$person_id = $titles['person_id'];

//Loop through images
$index = 1;
foreach ($images as $image) {
    $titles[$index]['person_id'] = $person_id;
    $titles[$index]['name'] = $image['name'];
    $index++;
}


var_dump($titles);

The result:

array(5) {
  ["person_id"]=>
  int(3)
  [1]=>
  array(4) {
    ["title"]=>
    string(8) "qwerqwer"
    ["medium"]=>
    string(10) "dfsadfasda"
    ["person_id"]=>
    int(3)
    ["name"]=>
    string(12) "_DSC0080.jpg"
  }
  [2]=>
  array(4) {
    ["title"]=>
    string(10) "sadfasdfad"
    ["medium"]=>
    string(8) "Asdfsadf"
    ["person_id"]=>
    int(3)
    ["name"]=>
    string(12) "_DSC0030.jpg"
  }
  [3]=>
  array(4) {
    ["title"]=>
    string(8) "asdfsadf"
    ["medium"]=>
    string(8) "Sadfsedf"
    ["person_id"]=>
    int(3)
    ["name"]=>
    string(12) "_DSC0001.jpg"
  }
  ["submit"]=>
  string(6) "Submit"
}

 

Link to post
Share on other sites

Your solution to the above problem was perfect.  But now I have another issue.  I end up with a multidimensional array and need to run that through a foreach loop.  As I run through the array I will be entering elements of each of the $title elements in a database.  Because a user may not enter information about all three images, I want to skip the elements of the $titles array that have empty elements.  I this case person_id will always be filled so the element is not entirely empty.  I tried using a conditional "continue;" but it didn't have any affect; all elements of $title are processed.  I've included a facsimile of the $titles array for reference.  I tried other things like !isset, and empty with the same results.  The fields are "not NULL" though I am told that isset and empty consider NULL empty.

I haven't found a function that checks to see if any element of an array is empty.  A key may be that the real trigger for continuing is if the filename is empty.  The others can be filled but I wouldn't want to enter them if no file was uploaded.  I couldn't get anything related to that element to work either.

--Kenoli

For example:

$titles = array (array('title', 'medium', 'person_id, filename'), array('title', 'medium', 'person_id, filename'), array('title', 'medium', 'person_id, filename'));


foreach ($titles as $values) {
	
	if ($values['title'] == '') { continue; }
	
	foreach ($values as $values_element) [
		
		// Enter elements of each $values_element in a database...
	]
	
	
}

 

Edited by kenoli
syntax errors and missing info.
Link to post
Share on other sites
50 minutes ago, kenoli said:

 I've included a facsimile of the $titles array for reference.

That is NOT a facsimile of your titles array. Your $titles  array has keys of "title", "medium" etc. That array above has values of "title", medium" etc with numeric keys.

Use print_r(array) on both to seee the difference.

Link to post
Share on other sites

I'm sorry about the ambiguity.  It was intended as a (lazy) reminder of the elements in the array.  The real issue was how to loop through the $titles array and exclude the array elements that are missing some of their own values.  If the elements were not arrays, I know how to do it.  I have not been able to figure out how to use an element that is missing a value to cause it to skip the entire $title element.  I spent along time trying everything I could think of.

--Kenoli

Link to post
Share on other sites

Here is the actual script.  I removed the first and last elements using array_shift and array_pop as they were not relevant.

You can see my attempt to use continue to skip an element in $title if it had an empty array element.  It did not work.  The script simply processed every element of $title.

--Kenoli


$titles {

  [1]=>
  array(4) {
    ["title"]=>
    string(8) "qwerqwer"
    ["medium"]=>
    string(10) "dfsadfasda"
    ["person_id"]=>
    int(3)
    ["name"]=>
    string(12) "_DSC0080.jpg"
  }
  [2]=>
  array(4) {
    ["title"]=>
    string(10) "sadfasdfad"
    ["medium"]=>
    string(8) "Asdfsadf"
    ["person_id"]=>
    int(3)
    ["name"]=>
    string(12) "_DSC0030.jpg"
  }
  [3]=>
  array(4) {
    ["title"]=>
    string(8) "asdfsadf"
    ["medium"]=>
    string(8) "Sadfsedf"
    ["person_id"]=>
    int(3)
    ["name"]=>
    string(12) "_DSC0001.jpg"
  }
}


foreach ($title as $title_elements) {
	
	if ($title_elements['title'] == '') { continue; }  //Attempt to skip array elements with and empty first element
		
	foreach($title_elements as $key => $value) {
		$param = ':' . $key;
		$stmt->bindParam($param, $$value);
		//echo '$' . "stmt->bindParam($param, $$key)<br>";  // Debug
	}
	
	foreach($title_elements as $key => $value) {
		$insert[$key] =  $value;
	}
	
	/** Execute statement using $insert array. */
	
	$stmt->execute($insert);
	
	} // End first foreach

 

Edited by kenoli
Link to post
Share on other sites

Why don't you RTFM to see what  $$ does?

try

$stmt = $conn->prepare("INSERT INTO mytable (title, medium, person_id, name)
                        VALUES (:title, :medium, :person_id, :name)
                        ");


foreach ($titles as $title_elements) {
    if ($title_elements['title'] != '') {
        $stmt->execute($title_elements);
    }
}

 

Link to post
Share on other sites

you also have a reply in your previous thread pointing out an issue with using both bindParam() and supplying an array to the ->execute(...) call -

Quote

don't use variable-variables, ever. they are not needed, ever, and for the posted code, those bindParam() statements aren't doing anything. you are overriding them by supplying an array to the ->execute(...) call. using bindParam/bindValue and supplying an array of values to the ->execute(...) call are mutually exclusive methods of supplying values to the query. you should simply supply an array of values to the ->execute(...) call.

 

Link to post
Share on other sites

I appreciate the help from both of you.  I've integrated your suggestions into my script and include it below.

It runs but nothing is entered into the table.

I have been struggling with PDO. and appreciate your comment Mac_gyver.  It helps clear some things up.

Any idea why the data is not being entered.

Thanks,

--Kenoli

<?php
	
//if(isset($_POST['submit'])){
	
	echo '<h4>Got to beginning of upload file</h4><br>';
	
	require 'Db.php';
	
	$person_id = $_POST['person_id'];

	$titles = $_POST;
	$images = $_FILES;
	
	
	$index = 1;
	foreach ($images as $image) {
	    $titles[$index]['person_id'] = $person_id;
	    $titles[$index]['filename'] = $image['name'];
	    $index++;
	}
	
	array_shift($titles);
	array_pop($titles);
	
	$sql = "INSERT INTO Images (person_id, title, medium, filename) VALUES (:person_id, :title, :medium, :filename)";
	
	$stmt = $pdo->prepare($sql);
		
	foreach ($titles as $title_elements) {
    if ($title_elements['title'] != '') {
        $stmt->execute($title_elements);
	    }
	}
     
    echo '<h4>Got to end of upload file</h4>';
		
//}	
	
	
?>

 

Link to post
Share on other sites

Brand & McGyver -- I really appreciate the help.  I'm feeling kind of like an idiot getting stuck so much. I don't do much of this and when I did more 15 years ago, felt a lot more adept.  PDO has gotten me confused and I'm distracted by a bunch of other stuff we're doing with a community art project hanging art banners up around town that makes it hard for me to put big blocks of time into the coding.  I'm trying to code a web site to track our banner making and let artists upload their images so we can turn them into banners. Your help is hugely appreciated. A good friend who codes professionally is lambasting me for staying with php.  He does everything with Javascript, both client and server side using vue.js.  PHP just makes a lot more sense to me.

Thanks for the heads up on error reporting.  Before I logged back in I was going to ask about it.  You mentioned this before and I checked the php.ini file and got this:

error_reporting=E_ALL & ~E_DEPRECATED & ~E_STRICT

I failed however to see further down that this:

display_errors=On

Had been turned off.  As you can see, I turned it on.

Is this all I need turned on regarding error reporting?

I had the impression I was getting less error reporting than I had expected.  I will reboot and try the script again to see if I get any error information back from PHP.  I have been getting some errors from PDO, largely if there is a connection issue.  I'm not getting it back on other pdo functions.

Regarding the bind-param issue, I got confused because I was trying to use the bind-param approach and it wasn't working and when I got feedback that all I had to do was send the array with key-value pairs I did that but left the bind-param code in place, not realizing it wasn't necessary.  I think it has screwed me up in a few other places.  I'm now clear about that.

--Kenoli

Link to post
Share on other sites

I'm getting the following error:

Parse error: syntax error, unexpected string content "", expecting "-" or identifier or variable or number in /Users/studio/Sites/BannerProject/b-as/_test_site/__classes/upload_files.php on line 64

Line 64 comes between the following two lines:

    $sql = "INSERT INTO Images (person_id, title, medium, filename) VALUES (:person_id, :title, :medium, :filename)";
    
    $stmt = $pdo->prepare($sql);

This follows:

foreach ($titles as $title_elements) {
    if ($title_elements['title'] != '') {
        $stmt->execute($title_elements);
        }
    }

--Kenoli
 

Link to post
Share on other sites
54 minutes ago, Barand said:

Are you sure it isn't referring to line 64 in a different file? It's not like the error reports to quote an empty line number.

That's the file and that's that's the line number.  I think the problem may be that there should be two "==" on line 66.  What do you think?  I'll try it.

--Kenoli

Link to post
Share on other sites
5 minutes ago, kenoli said:

That's the file and that's that's the line number.  I think the problem may be that there should be two "==" on line 66.  What do you think?  I'll try it.

--Kenoli

I get the same error with !== .

When I take the conditional out, I get:

Fatal error: Uncaught PDOException: SQLSTATE[HY093]: Invalid parameter number: parameter was not defined in /Users/studio/Sites/BannerProject/b-as/_test_site/__classes/upload_images.php:75 Stack trace: #0 /Users/studio/Sites/BannerProject/b-as/_test_site/__classes/upload_images.php(75): PDOStatement->execute(Array) #1 {main} thrown in /Users/studio/Sites/BannerProject/b-as/_test_site/__classes/upload_images.php on line 75

--Kenoli

Link to post
Share on other sites

There are the same number of elements in the title array as are indicated in the sql statement.  I noticed that when I echo $titles in print_r the added elements have no quotation marks and the ones that arrived via the $_POST file do.  Does that matter?  Here's a printout of $titles just before it is executed:

Array
(
    [0] => Array
        (
            ['title'] => qwerwqe
            ['medium'] => Qwerwqer
            [person_id] => 4
            [filename] => _DSC0080.jpg
        )

    [1] => Array
        (
            ['title'] => Qwerweqr
            ['medium'] => Qwerwqer
            [person_id] => 4
            [filename] => _DSC0001.jpg
        )

    [2] => Array
        (
            ['title'] => weqrweqr
            ['medium'] => Wqerweqr
            [person_id] => 4
            [filename] =>  reportout.jpg
        )

)

 

Link to post
Share on other sites

print_r() doesn't normally put quotes around keys, just [..]. EG

Array
(
    [fname] => joe
    [lname] => bloggs
)

If you have them, your form must be adding them to the input field names.

Show your form code.

Link to post
Share on other sites

odd syntax errors are often caused by copy/pasting code from web pages where it has been 'published' and 'beautified'. it contains non-ascii characters that when treated in a php code context breaks the php code. the solution is to delete and re-type the line of code.

48 minutes ago, kenoli said:

the ones that arrived via the $_POST file do

there should be no quotes in the print_r() output around the associative array index names (just tested.) there's something going in your form field name attributes. what is the code/markup for your form fields?

Edited by mac_gyver
Link to post
Share on other sites
1 hour ago, mac_gyver said:

odd syntax errors are often caused by copy/pasting code from web pages where it has been 'published' and 'beautified'. it contains non-ascii characters that when treated in a php code context breaks the php code. the solution is to delete and re-type the line of code.

there should be no quotes in the print_r() output around the associative array index names (just tested.) there's something going in your form field name attributes. what is the code/markup for your form fields?

I have to do something else just now but was thinking some of what you are thinking and appreciate all the thoughts.  I will work on it as soon as I can get back to it, hopefully today.  I am getting good error reporting.  Again, many thanks.

--Kenoli

Link to post
Share on other sites

I re-typed everything I had copied and pasted having had the same thoughts you had.  It did get rid of an earlier issue but it still fails.  The errors are described below.  

I am including my form code below as you requested.  I was not sure exactly how to set it up but the way I did gave me a POST array I could work with.

I get the following error when I run the script with the conditional as I go it from this discussion.  Line 71 is

if ($title_elements['title'] != '').

Warning: Undefined array key "title" in /Users/studio/Sites/BannerProject/b-as/_test_site/__classes/upload_images.php on line 71

Warning: Undefined array key "title" in /Users/studio/Sites/BannerProject/b-as/_test_site/__classes/upload_images.php on line 71

Warning: Undefined array key "title" in /Users/studio/Sites/BannerProject/b-as/_test_site/__classes/upload_images.php on line 71

I get this error when I run it without the conditional.  Line 72 is 

$stmt->execute($title_elements);

Fatal error: Uncaught PDOException: SQLSTATE[HY093]: Invalid parameter number: parameter was not defined in /Users/studio/Sites/BannerProject/b-as/_test_site/__classes/upload_images.php:72 Stack trace: #0 /Users/studio/Sites/BannerProject/b-as/_test_site/__classes/upload_images.php(72): PDOStatement->execute(Array) #1 {main} thrown in /Users/studio/Sites/BannerProject/b-as/_test_site/__classes/upload_images.php on line 72

<!DOCTYPE HTML>
<html>
	
<head>

<title>Image Input Form</title>
 
<LINK REL=StyleSheet HREF="../css/css-form_new.css" TYPE="text/css" MEDIA=screen>

</head>

<body>
	
<div class="container">
  
<div class="sectionHeading">Submit Images to Taking it Outdoors</div>
      
<form action="../__classes/upload_images.php" method = "POST" enctype = "multipart/form-data">
<input type="hidden" id="custId" name="person_id" value="<?php echo $_POST['person_id'];?>">
  
 <!-- Start Artwork -->
	<h4>Upload up to three files in JPG, JPEG, PNG or TIF(F) format.</h4>
	<strong>File size:</strong> We recommend at least a <strong>2MB</strong> file and  no larger than a <strong>20MB</strong> file.  Take into account the speed of your internet connection.  Large files can take a long time to uplaod if you have a slow connection.
	<p><strong>Larger Files:</strong> For very high resolution larger files (<strong>>100MB</strong>) we recommend using <a href="wetransfer.com">wetransfer.com</a>, a free file transfer service for files up to <strong>2 GB</strong>.</p>
	
	<div class="fileUpload" >Image 1:</div>
		<label for="title1"><span>Artwork Title </span><input type="text" class="input-field" name="1['title']" value="" /></label>
		<label for="medium1"><span>Medium<span class="required">*</span></span><input type="text" class="input-field" name="1['medium']" value="" /></label>
		<label for="image1"><span>Image File 1</span><input type="file" name="image1" ></label></span></label>
	
	<div class="fileUpload" >Image 2:</div>
		<label for="title2"><span>Artwork Title </span><input type="text" class="input-field" name="2['title']" value="" /></label>
		<label for="medium2"><span>Medium<span class="required">*</span></span><input type="text" class="input-field" name="2['medium']" value="" /></label>
		<label for="image2"><span>Image File 2</span><input type="file" name="image2"></label></span>
		
	<div class="fileUpload" >Image 3:</div>	
		<label for="title3"><span>Artwork Title </span><input type="text" class="input-field" name="3['title']" value="" /></label>
		<label for="medium3"><span>Medium<span class="required">*</span></span><input type="text" class="input-field" name="3['medium']" value="" /></label>
		<label for="image3"><span>Image File 3</span><input type="file" name="image3"></label></span>
		
	</div>
<!-- End Artwork -->
	
	<p><input type = "submit" name="submit"/>
	<a href="http://localhost/Sites/BannerProject/b-as/_test_site/index.php"><input type = "button" class="blue" name="Cancel" value="Cancel"/></a></p>		

</form>
 
</div>
      
</body>
</html>

 

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.