What I have here is a delete multiple file function in codeigniter. I need to merge or concat the value only of associative array. The value of both array was the file name and file extension of an image/file. I used md5 to change the name of the file.
This is my code
public function delete_files(){
$filesCount = count($_FILES['file_certificate']['name']);
$file_certificate = [];
$y = 0;
for($i = 0; $i < $filesCount; $i++){
$_FILES['file_certificates']['name'] = $_FILES['file_certificate']['name'][$i];
$_FILES['file_certificates']['type'] = $_FILES['file_certificate']['type'][$i];
$_FILES['file_certificates']['tmp_name'] = $_FILES['file_certificate']['tmp_name'][$i];
$_FILES['file_certificates']['error'] = $_FILES['file_certificate']['error'][$i];
$_FILES['file_certificates']['size'] = $_FILES['file_certificate']['size'][$i];
$oldname = $_FILES["file_certificates"]['name'];
$file_ext[] = pathinfo($oldname,PATHINFO_EXTENSION);
$file_ray[] = trim(strtolower(md5(time().$oldname)));
$result = array_combine($file_ray, $file_ext);
}
$path = FCPATH . 'uploads/certificate/';
array_map('unlink', $result);
}
Here's my array right now
enter image description here
I need it like this
Array
(
[0] => 46eced0ea722a94160d53b4abbb10381.jpg
[1] => 4f9ca54fa1daa022dc31b991a673cab7.pdf
)
And also I never try this if its works deleting a multiple file via this code
$path = FCPATH . 'uploads/certificate/'; //path file location
array_map('unlink', $result);
Thank you.
I got this done using foreach.
$path = FCPATH . 'uploads/certificate/';
$data = array();
foreach( $file_ray as $index => $code ) {
$value = $path.$code.'.'.$file_ext[$index];
$data[] = $value;
}
Related
How would you transform a monodimensional array into a multidimensional array in PHP? Suppose you have something like this
$array['breakfast'] = 'milk';
$array['meal.firstdish'] = 'pasta';
$array['meal.seconddish.maincourse'] = 'veal';
$array['meal.seconddish.dressing'] = 'fries';
$array['meal.dessert'] = 'pie';
And you want a function to transform it into
$array['breakfast'] = 'milk';
$array['meal']['firstdish'] = 'pasta';
$array['meal']['seconddish']['maincourse'] = 'veal';
$array['meal']['seconddish']['dressing'] = 'fries';
$array['meal']['dessert'] = 'pie';
The same function should of course transform
$tire['ean'] = '3286347717116';
$tire['brand.maker'] = 'BRIDGESTONE';
$tire['brand.model.name'] = 'POTENZA';
$tire['brand.model.variant'] = 'RE 040 RFT * SZ';
into
$tire['ean'] = '3286347717116';
$tire['brand']['maker'] = 'BRIDGESTONE';
$tire['brand']['model']['name'] = 'POTENZA';
$tire['brand']['model']['variant'] = 'RE 040 RFT * SZ';
I was thinking of using explode, then eval on the results, but eval always feels like cheating to me and I guess it would keep my code from running in HipHop.
The reason I want to do this is that I have to export lots of different tables from a database into XML files, and I already have a robust function that turns a multidimensional array into XML.
Like this:
function build(array &$trg, array $k,$key,$value) {
$p = &$trg;
while ( !empty($k) ) {
$nk = array_shift($k);
if ( !isset($p[$nk]) ) {
$p[$nk] = [];
}
$p = &$p[$nk];
}
$p[$key] = $value;
return $p;
}
$array['breakfast'] = 'milk';
$array['meal.firstdish'] = 'pasta';
$array['meal.seconddish.maincourse'] = 'veal';
$array['meal.seconddish.dressing'] = 'fries';
$array['meal.dessert'] = 'pie';
$out = [];
foreach ($array as $key => $value ) {
$path = explode('.',$key);
$last = array_pop($path);
build($out,$path,$last,$value);
}
print_r($out);
You were on the right track with explode, but there's no need to use eval. Once you've got the pieces of the keys available, you can loop over them and incrementally assign a pointer into a new array:
<?php
$array['breakfast'] = 'milk';
$array['meal.firstdish'] = 'pasta';
$array['meal.seconddish.maincourse'] = 'veal';
$array['meal.seconddish.dressing'] = 'fries';
$array['meal.dessert'] = 'pie';
$result = [];
$target = null;
foreach ($array as $key => $value) {
// Start by targeting the base of our resulting array
$target =& $result;
// Break the keys apart into pieces
$keyParts = explode('.', $key);
// Assign new target based on indexing into the result array one "piece" at a time
while ($part = array_shift($keyParts)) {
$target =& $target[$part];
}
// Finally, assign the value to our target
$target = $value;
}
See https://eval.in/625627
I am building an application using Laravel 5 where I want to insert several image urls within an array separated by commas. This would be placed in a column on the database. The files are successfully uploaded to my AWS S3 bucket, but it's now the input to the database. I tried using Laravel's array_add helper but I get an error stating I am missing argument 2. I am wondering how would I be able to achieve this. My current alternate solution is to put the images with the post id and use the relationship to connect them together.
For reference: The column I intend to place the images is picgallery, and the insert is done using $newproperty['picgallery'] variable.
public function store(Request $request)
{
//establish random generated string for gallery_id
$rando = str_random(8);
//input all data to database
$data = $request->all();
$newproperty['title'] = $data['title'];
$newproperty['address'] = $data['address'];
$newproperty['city'] = $data['city'];
$newproperty['province'] = $data['province'];
$newproperty['contact_person'] = Auth::user()->id;
$newproperty['gallery_id'] = $rando;
$newproperty['property_description'] = $data['description'];
if($request->hasfile('images')) {
$files = $request->file('images');
//storage into AWS
foreach ($files as $file) {
$uploadedFile = $file;
$upFileName = time() . '.' . $uploadedFile->getClientOriginalName();
$filename = strtolower($upFileName);
$s3 = \Storage::disk('s3');
$filePath = 'properties/' . $rando . '/' . $filename;
$s3->put($filePath, file_get_contents($uploadedFile), 'public');
$propicurl = 'https://s3-ap-southeast-1.amazonaws.com/cebuproperties/' . $filePath;
$array = array_add(['img'=> '$propicurl']);
$newproperty['picgallery'] = $array;
}
}
Properties::create($newproperty);
return redirect('/properties');
}
array_add requires 3 parameters
$array = array_add($array, 'key', 'value');
(https://laravel.com/docs/5.1/helpers#method-array-add)
For example
$testArray = array('key1' => 'value1');
$testArray = array_add($testArray, 'key2', 'value2');
and you will get
[
"key1" => "value1",
"key2" => "value2",
]
You might not be able to use array_add in this case.
I think in order to fix your issue, fix your foreach loop to be something like this
//storage into AWS
// init the new array here
$array = [];
foreach ($files as $file) {
$uploadedFile = $file;
$upFileName = time() . '.' . $uploadedFile->getClientOriginalName();
$filename = strtolower($upFileName);
$s3 = \Storage::disk('s3');
$filePath = 'properties/' . $rando . '/' . $filename;
$s3->put($filePath, file_get_contents($uploadedFile), 'public');
$propicurl = 'https://s3-ap-southeast-1.amazonaws.com/cebuproperties/' . $filePath;
// change how to use array_add
array_push($array, array('img' => $propicurl));
// remove the below line
// $array = array_add($array, 'img', $propicurl);
}
// move this assignment out of foreach loop
$newproperty['picgallery'] = $array;
Sorry for if my title is wrong.
Let me explain in detail here.
I want to store each filename in number-wise in php variable like
$image0 = filename.jpg
$image1 = filename.jpg
$image2 = filename.jpg
$image3 = filename.jpg
so on..
this filename.jpg is generate from for loop below is my code, current OP and expected OP.
$t = glob("/var/www/localhostmyproject.com/media/catalog/product/uploads/".$productnumber."/".$productnumber."*", GLOB_BRACE);
print_r($t);
for ($i = 0; $i <= 5; $i++) {
//$t =asort($t);
$proinfo = $t[$i];
$path_parts = pathinfo($proinfo);
echo $path_parts['basename'], "\n";
echo $imagename = "/uploads/".$productnumber."/".$path_parts['basename']."\n\n";
}
Current OP
Array
(
[0] => /var/www/localhostmyproject.com/media/catalog/product/uploads/8573228/8573228a.jpg
[1] => /var/www/localhostmyproject.com/media/catalog/product/uploads/8573228/8573228b.jpg
[2] => /var/www/localhostmyproject.com/media/catalog/product/uploads/8573228/8573228c.jpg
[3] => /var/www/localhostmyproject.com/media/catalog/product/uploads/8573228/8573228d.jpg
}
8573228a.jpg
/uploads/8573228/8573228a.jpg
8573228b.jpg
/uploads/8573228/8573228b.jpg
8573228c.jpg
/uploads/8573228/8573228c.jpg
8573228d.jpg
/uploads/8573228/8573228d.jpg
Expected OP
Array
(
[0] => /var/www/localhostmyproject.com/media/catalog/product/uploads/8573228/8573228a.jpg
[1] => /var/www/localhostmyproject.com/media/catalog/product/uploads/8573228/8573228b.jpg
[2] => /var/www/localhostmyproject.com/media/catalog/product/uploads/8573228/8573228c.jpg
[3] => /var/www/localhostmyproject.com/media/catalog/product/uploads/8573228/8573228d.jpg
}
8573228a.jpg
/uploads/8573228/8573228a.jpg
$image0 = "/uploads/8573228/8573228a.jpg";
8573228b.jpg
/uploads/8573228/8573228b.jpg
$image1="/uploads/8573228/8573228b.jpg";
8573228c.jpg
/uploads/8573228/8573228c.jpg
$image2="/uploads/8573228/8573228c.jpg";
8573228d.jpg
/uploads/8573228/8573228d.jpg
$image3="/uploads/8573228/8573228d.jpg";
So I can use this variable $image0,$image1,$image2,$image3 in mysql query to insert data.
I tried to add this line inside for loop after echo $imagearr. But its not showing expected OP.
echo $image.$i = $path_parts[filename].$i."\n";
Please let me know how can I achieve this.
EDIT
Updated $imagearr variable name to $imagename. It might confuse to others between array $t**
You can achieve it by assigning dynamic variables (Variable Variables as Darren commented correctly) like so:
$files = ['sunset.jpg', 'moon.jpg', 'jupiter.png', 'banana.gif'];
$count = 0;
foreach($files as $file) {
${'file' . $count} = $file;
$count++;
}
// output gives you 4 strings
var_dump($file0, $file1, $file2, $file3);
Since you are already getting multiple filenames and upload directory path, and you just need to assign to an auto-increment variable.
You just need to add this :
echo $image.$i=$imagename; // it will give desired output '$image2="/uploads/8573228/8573228c.jpg";'
Your complete code :
$t = glob("/var/www/localhostmyproject.com/media/catalog/product/uploads/".$productnumber."/".$productnumber."*", GLOB_BRACE);
print_r($t);
for ($i = 0; $i <= 5; $i++) {
//$t =asort($t);
$proinfo = $t[$i];
$path_parts = pathinfo($proinfo);
echo $path_parts['basename'], "\n";
echo $imagename= "/uploads/".$productnumber."/".$path_parts['basename']."\n\n";
echo $image.$i = $imagename; // it will give desired output '$image2="/uploads/8573228/8573228c.jpg";'
}
try this example:
<?php
$array = array("variable1" => "value1","variable2" => "value2", "variable3" => "value3");
extract($array);
var_dump($variable1);
var_dump($variable2);
var_dump($variable3);
?>
output:
string(6) "value1" string(6) "value2" string(6) "value3"
In your case the following code should work:
$t = glob("/var/www/localhostmyproject.com/media/catalog/product/uploads/".$productnumber."/".$productnumber."*", GLOB_BRACE);
$images = array();
for ($i = 0; $i <= 5; $i++) {
$proinfo = $t[$i];
$path_parts = pathinfo($proinfo);
$imagename = "/uploads/".$productnumber."/".$path_parts['basename'];
$images['image'.$i] = $imagename;
}
extract($images);
var_dump($image0);
var_dump($image1);
var_dump($image2);
var_dump($image3);
var_dump($image4);
var_dump($image5);
?>
Put this in your code, you can get output:
echo $imagearr = "/uploads/".$productnumber."/".$path_parts['basename']."\n\n";
echo $image.$i=$imagearr;
I am trying to represent the whole array returned from Amazon S3 bucket in a tree structure one can browse.
The array example is following
$files[0] = 'container/798/';
$files[1] = 'container/798/logo.png';
$files[2] = 'container/798/test folder/';
$files[3] = 'container/798/test folder/another folder/';
$files[4] = 'container/798/test folder/another folder/again test/';
$files[5] = 'container/798/test folder/another folder/test me/';
$files[6] = 'container/798/test two/';
$files[7] = 'container/798/test two/logo2.png';
and this is what i am trying to achieve
http://i.stack.imgur.com/HBjvE.png
so far i have only achieved differing the files and folder but not on different level with parent-child relation. The above mentioned array resides in $keys['files']. The code is following
$keys = json_decode($result,true);
$folders = array();
$files = array();
$i =0;
foreach ($keys['files'] as $key){
if(endsWith($key, "/")){
$exploded = explode('container/'.$_SESSION['id_user'].'/',$key);
if(!empty($exploded[1]))
$folders[$i]['name'] = substr($exploded[1],0,-1);
}
else{
$exploded = explode('container/'.$_SESSION['id_user'].'/',$key);
$files[$i]['name'] = $exploded[1];
$files[$i]['size'] = "";
$files[$i]['date'] = "";
$files[$i]['preview_icon'] = "";
$files[$i]['dimensions'] = "";
$files[$i]['url'] = "";
}
$i++;
}
This is code just to show i am trying but its not complete or accurate. I don't know how to approach a logic that can give me the hierarchy i am showing the picture. Any help would be greatly appreciated.
I don't know if this is the 'correct' way to do this, but if you want to make a recursive structure, then the easy way is to use a recursive function:
$root = array('name'=>'/', 'children' => array(), 'href'=>'');
function store_file($filename, &$parent){
if(empty($filename)) return;
$matches = array();
if(preg_match('|^([^/]+)/(.*)$|', $filename, $matches)){
$nextdir = $matches[1];
if(!isset($parent['children'][$nextdir])){
$parent['children'][$nextdir] = array('name' => $nextdir,
'children' => array(),
'href' => $parent['href'] . '/' . $nextdir);
}
store_file($matches[2], $parent['children'][$nextdir]);
} else {
$parent['children'][$filename] = array('name' => $filename,
'size' => '...',
'href' => $parent['href'] . '/' . $filename);
}
}
foreach($files as $file){
store_file($file, $root);
}
Now, every element of root['children'] is an associative array that hash either information about a file or its own children array.
so if I have a string like this, e.g. "/path1/folder/fun/yay/"
How can I run that through a function to return an array of all the parent paths, looking like this:
array (
'/',
'/path1/',
'/path1/folder/',
'/path1/folder/fun/',
'/path1/folder/fun/yay/'
)
This is what I have so far, obviously it doesn't work and it's confusing to say the least...
$a = explode('/',$path); $ii = 0; $path_array = array();
for ($i = 0; $i < sizeof($a); $i++) {
if ($a[$i]) {
$path_array[$ii] = "";
for ($n = 0; $n < $i; $n++)
{
$path_array[$ii] .= $a[$n];
}
$ii++;
}
}
file_put_contents('text.txt',serialize($path_array));
Thanks!
BTW my end goal here is to be able to run an SQL query on a table of folder paths to increment a value on a folder and all of its parents.
Maybe there's some sort of SQL operator where I could select all rows whose path is a part of the path I input? Kinda like this in reverse:
mysqli_query($mysqli,'UPDATE content_folders SET size = size+'.filesize("content/$id").' WHERE path LIKE "'.$path.'%"')
As for the PHP function - something like this would work:
function returnAllPaths ( $fullPath = '/' , Array $pathHistory = array() )
{
while ( strlen($fullPath) > 1 AND $fullPath[0] === '/' )
{
array_push($pathHistory, $fullPath);
$fullPath = preg_replace('%(.*/)[^/]+(?:/)?$%is', '$1', $fullPath);
}
array_push($pathHistory, $fullPath);
return array_reverse($pathHistory);
}
You can use this
$path = '/path1/folder/fun/yay/';
$path = explode('/',$path);
$path = array_filter($path);
$iniVal = '';
$array_paths = array();
array_push($array_paths,'/');
foreach($path as $array){
$value = $iniVal.'/'.$array.'/';
array_push($array_paths,$value);
$iniVal .= '/'.$array;
}
//print_r($array_paths);
Output would display in array such as :
Array ( [0] => / [1] => /path1/ [2] => /path1/folder/ [3] => /path1/folder/fun/ [4] => /path1/folder/fun/yay/ )
same as
array (
'/',
'/path1/',
'/path1/folder/',
'/path1/folder/fun/',
'/path1/folder/fun/yay/'
)
DEMO : PHP FIDDLE