PHP MySQL multiple image URL fields array - php

In building a website for a friend the database has a row with 39 fields for images.
In the field is the name of the image (e.g. "my_image.jpg") not the image itself (BLOB).
i.e.: image_01, image_02, image_03 and so forth.
I have PHP generating the while loop and getting the information without problems.
I'm trying to get all the images into one array so I can display the pictures from that one row as a gallery.
I hope someone can offer me a way forward as I've tried without success.
from while loop:
$MEDIA_IMAGE_00 = $row["MEDIA_IMAGE_00"];
$MEDIA_IMAGE_01 = $row["MEDIA_IMAGE_01"];
$MEDIA_IMAGE_02 = $row["MEDIA_IMAGE_02"];
I need to echo out as
["propimages/$MEDIA_IMAGE_00", "", "", "$MEDIA_IMAGE_TEXT_00"],
["propimages/$MEDIA_IMAGE_01", "", "", "$MEDIA_IMAGE_TEXT_01"],
["propimages/$MEDIA_IMAGE_02", "", "", "$MEDIA_IMAGE_TEXT_02"]
for them to display in a gallery.
EDIT:
while($row = mysql_fetch_array($sqlSearch)){
$propid = $row["propid"];
$MEDIA_IMAGE_00 = $row["MEDIA_IMAGE_00"];
$MEDIA_IMAGE_01 = $row["MEDIA_IMAGE_01"];
$MEDIA_IMAGE_02 = $row["MEDIA_IMAGE_02"];
$MEDIA_IMAGE_33 = $row["MEDIA_IMAGE_33"];
$MEDIA_IMAGE_34 = $row["MEDIA_IMAGE_34"];
$MEDIA_IMAGE_35 = $row["MEDIA_IMAGE_35"];
}

I'm assuming that $propid is what identifies the row itself and that 'MEDIA_IMAGE_TEXT' is available in the same row:
$properties = array();
while ($row = mysql_fetch_array($sqlSearch)) {
$propid = $row["propid"];
$images = array();
for ($i = 0; $i <= 35; ++$i) {
$imageId = "MEDIA_IMAGE_" . str_pad($i, 2, '0', STR_PAD_LEFT);
if ($row[$imageId]) {
$images[] = array(
$row[$imageId],
'',
'',
$row["MEDIA_IMAGE_TEXT_" . str_pad($i, 2, '0', STR_PAD_LEFT)],
);
}
}
$properties[] = array(
'id' => $propid,
'images' => $images,
);
echo json_encode($properties);
It generates a list of properties, each having an id and an array of images; each image comprises the location (I guess) and the title / description.

Why don't you build an array of images in your while loop ?
$images = array()
$i = 0;
While(...) {
$images[] = $row["MEDIA_IMAGE_0$i"];
$i++;
[...]
}
The you get an array that you ca use in a foreach and display your row(s). On the principle that should work, i think ;)

Related

How to merge values from similar rows in an array to rows containing both data in php

I have a phone book array I get from a database, where everyone appears once with their stationary phone number and a second with their mobile number.
I need to make this an array where everyone has only one line, with their phone number and mobile number
//My array
$data = array(
array('name'=>'robert','family'=>'bridgstone','home'=>'0258101234'),
array('name'=>'robert','family'=>'bridgstone','phone'=>'07258101235'),
array('name'=>'dan','family'=>'swartz','home'=>'098101244'),
array('name'=>'ben','family'=>'wais','home'=>'0447256155778'),
array('name'=>'ben','family'=>'wais','phone'=>'04472861558878'),
);
//The result that should come out
$data = array(
array('name'=>'robert','family'=>'bridgstone','home'=>'0258101234','phone'=>'07258101235'),
array('name'=>'dan','family'=>'swartz','home'=>'098101244','phone'=>''),
array('name'=>'ben','family'=>'wais','home'=>'0447256155778','phone'=>'04472861558878')
);
I would do it the following way:
first I would generate a unique key that identify the row (in your case the name and the family, for example).
then check if a element with the same key exist, if it already exist merge the two component.
Optional if you only want an array of values transform the result with array_value function.
$dataArray = array(
array('name'=>'robert','family'=>'bridgstone','home'=>'0258101234'),
array('name'=>'robert','family'=>'bridgstone','phone'=>'07258101235'),
array('name'=>'dan','family'=>'swartz','home'=>'098101244'),
array('name'=>'ben','family'=>'wais','home'=>'0447256155778'),
array('name'=>'ben','family'=>'wais','phone'=>'04472861558878'),
);
$result = [];
foreach($dataArray as $data){
//Just in case that the name or the family is not assigned (operator ??)
$key = ($data['name']??'').'-'.($data['family']??'');
$result[$key] = array_merge($result[$key]??[],$data);
}
//Optional, get only the array values
$result = array_values($result);
I did so
$data = array(
array('name'=>'robert','family'=>'bridgstone','home'=>'0258101234'),
array('name'=>'robert','family'=>'bridgstone','phone'=>'07258101235'),
array('name'=>'dan','family'=>'swartz','home'=>'098101244'),
array('name'=>'ben','family'=>'wais','home'=>'0447256155778'),
array('name'=>'ben','family'=>'wais','phone'=>'04472861558878'),
);
count($data) < 2 ? exit(): $data;
for($i=0;$i<count($data);$i++){
$array_unique[$i] = $data[$i]["name"];
$array_unique[$i] = $data[$i]["family"];
}
$array_unique = array_unique($array_unique);
if(count($array_unique) == 1){
$last_array[0]=$array_unique[0];
$last_array[0]["phone"]=$array_unique[0]["phone"];
}
else{
$array_uniqueKeys = array_keys($array_unique);
for($i = 0;$i < count($array_unique);$i++){
$firstIndex = $i + 1;
$firstIndex == count($array_unique) ? $nextKey = count($data) : $nextKey = $array_uniqueKeys[$firstIndex];
$paar = $nextKey - $array_uniqueKeys[$i];
$dataslice = array();
$i3=0;
for($i2 = $array_uniqueKeys[$i];$i2 < ($array_uniqueKeys[$i]+$paar);$i2++){
if(in_array($i2,$array_uniqueKeys)){
$last_array[$i]=$data[$i2];
}
else{
$last_array[$i]["phone"]=$data[$i2]["phone"];
}
$i3++;
}
}
}
print_r($last_array);

CodeIgniter one query multiple statements

I use CodeIgniter, and when an insert_batch does not fully work (number of items inserted different from the number of items given), I have to do the inserts again, using insert ignore to maximize the number that goes through the process without having errors for existing ones.
When I use this method, the kind of data I'm inserting does not need strict compliance between the number of items given, and the number put in the database. Maximize is the way.
What would be the correct way of a) using insert_batch as much as possible b) when it fails, using a workaround, while minimizing the number of unnecessary requests?
Thanks
The Correct way of inserting data using insert_batch is :
CI_Controller :
public function add_monthly_record()
{
$date = $this->input->post('date');
$due_date = $this->input->post('due_date');
$billing_date = $this->input->post('billing_date');
$total_area = $this->input->post('total_area');
$comp_id = $this->input->post('comp_id');
$unit_id = $this->input->post('unit_id');
$percent = $this->input->post('percent');
$unit_consumed = $this->input->post('unit_consumed');
$per_unit = $this->input->post('per_unit');
$actual_amount = $this->input->post('actual_amount');
$subsidies_from_itb = $this->input->post('subsidies_from_itb');
$subsidies = $this->input->post('subsidies');
$data = array();
foreach ($unit_id as $id => $name) {
$data[] = array(
'date' => $date,
'comp_id' => $comp_id,
'due_date' => $due_date,
'billing_date' => $billing_date,
'total_area' => $total_area,
'unit_id' => $unit_id[$id],
'percent' =>$percent[$id],
'unit_consumed' => $unit_consumed[$id],
'per_unit' => $per_unit[$id],
'actual_amount' => $actual_amount[$id],
'subsidies_from_itb' => $subsidies_from_itb[$id],
'subsidies' => $subsidies[$id],
);
};
$result = $this->Companies_records->add_monthly_record($data);
//return from model
$total_affected_rows = $result[1];
$first_insert_id = $result[0];
//using last id
if ($total_affected_rows) {
$count = $total_affected_rows - 1;
for ($x = 0; $x <= $count; $x++) {
$id = $first_insert_id + $x;
$invoice = 'EBR' . date('m') . '/' . date('y') . '/' . str_pad($id, 6, '0', STR_PAD_LEFT);
$field = array(
'invoice_no' => $invoice,
);
$this->Companies_records->add_monthly_record_update($field,$id);
}
}
echo json_encode($result);
}
CI_Model :
public function add_monthly_record($data)
{
$this->db->insert_batch('monthly_record', $data);
$first_insert_id = $this->db->insert_id();
$total_affected_rows = $this->db->affected_rows();
return [$first_insert_id, $total_affected_rows];
}
AS #q81 mentioned, you would split the batches (as you see fit or depending on system resources) like this:
$insert_batch = array();
$maximum_items = 100;
$i = 1;
while ($condition == true) {
// code to add data into $insert_batch
// ...
// insert the batch every n items
if ($i == $maximum_items) {
$this->db->insert_batch('table', $insert_batch); // insert the batch
$insert_batch = array(); // empty batch array
$i = 0;
}
$i++;
}
// the last $insert_batch
if ($insert_batch) {
$this->db->insert_batch('table', $insert_batch);
}
Edit:
while insert batch already splits the batches, the reason why you have "number of items inserted different from the number of items given" might be because the allowed memory size is reached. this happened to me too many times.

PHP Excel performance is slow

I want to generate an excel sheet which contain some default fields and variable number of comment fields and data related to comment. I want to set specific width and wrap text for comment fields.Righ now I am using this code
$excelObj = new \PHPExcel();
$ews = $excelObj->getSheet(0);
$ews->setTitle('SurveyDetails');
$ews->fromArray($header, ' ', 'A1'); //Write the header from array
$ews->fromArray($content_arr, ' ', 'A2'); // Write the content from array
$header_style = array(
'font' => array('bold' => true,),
'alignment' => array('horizontal' => \PHPExcel_Style_Alignment::HORIZONTAL_CENTER, 'vertical' => \PHPExcel_Style_Alignment::VERTICAL_CENTER),
);
$content_style = array(
'alignment' => array('horizontal' => \PHPExcel_Style_Alignment::HORIZONTAL_CENTER, 'vertical' => \PHPExcel_Style_Alignment::VERTICAL_CENTER),
);
$start_end_columns = $excelObj->setActiveSheetIndex(0)->calculateWorksheetDimension();
preg_match_all('!\d+!', $start_end_columns, $matches);
$numbers = implode(':', $matches[0]);
$columns = explode(":", $numbers);
$header_end_column_no = $columns[1];
$header_start_end = str_replace($header_end_column_no, 1, $start_end_columns); // A1:G1
$ews->getStyle($header_start_end)->applyFromArray($header_style);
$start_end_columns = str_replace("A1", "A2", $start_end_columns); // Start column of content changed A1 to A2
$ews->getStyle($start_end_columns)->applyFromArray($content_style);
$cols = explode(":", $start_end_columns);
$endColmn = $cols[1];
$endColmn = preg_replace('/[0-9]+/', '', $endColmn);
$activeSheetObj = $excelObj->getActiveSheet();
//Set the autosize height for all the cells
$activeSheetObj->getDefaultRowDimension()->setRowHeight(-1);
$this->log(sprintf("Before set hyper link excel projectId : %s, surveyId : %s", $projectId, $survey_id), LogLevel::INFO);
//Set the hyperlink in the path field
$i = 2;
$count = count($content_arr);
foreach ($content_arr as $content) {
$activeSheetObj->getCell('F' . $i)->getHyperlink()->setUrl($content['path']);
$i++;
}
$activeSheetObj->getStyle('G'.'2:'.'G'.$count)->getAlignment()->setWrapText(true);
$this->log(sprintf("After setting hyper link projectId : %s, surveyId : %s", $projectId, $survey_id), LogLevel::INFO);
//Set specific width for the note and comment fields
$activeSheetObj->getColumnDimension('G')->setWidth(35);
$l = 0;
if (strcmp('G', $endColmn) != 0) {
for ($col = 'J'; $col != $endColmn; $col++) {
if ($l % 3 == 0) {
$activeSheetObj
->getColumnDimension($col)
->setWidth(35);
$activeSheetObj->getStyle($col.'2:'.$col.$count)->getAlignment()->setWrapText(true);
}
$l++;
}
$activeSheetObj->getColumnDimension($endColmn)->setWidth(35);
$activeSheetObj->getStyle($endColmn.'2:'.$endColmn.$count)->getAlignment()->setWrapText(true);
}
unset($content_arr);
$this->log(sprintf("After setting width projectId : %s, surveyId : %s", $projectId, $survey_id), LogLevel::INFO);
$writer = \PHPExcel_IOFactory::createWriter($excelObj, 'Excel2007');
//Save to perticular location
$keyname = "videos/Export/" . $projectId . "/" . $fileName;
$writer->save('/home/senchu/Documents/Infrass.xlsx');
But it takes about 3 seconds to complete the process on 10 columns and 400 rows. Is there any way to optimize this code so that to increase the performance. When I tried caching I didn't get much performance improvement.
Instead of iterating each row and setting hyper link like
$activeSheetObj->getCell('F' . $i)->getHyperlink()->setUrl($content['path']);
is there any method to set hyper link from array.so that we can avoid this much number of iterations.

How do i update multiple rows with multiple condition in Code Igniter

I am just learning PHP and using the Codeigniter framework.
I'm using this code in my controller when inserting new data and it's working.
//INSERT MULTI ROWS TABEL harga_inventori
$kode_inventori = $_POST['kode_inventori'];
$result = array();
foreach($_POST['kode_kategori_pelanggan'] AS $key => $val){
$result[] = array(
"kode_kategori_pelanggan" => $_POST['kode_kategori_pelanggan'][$key],
"kode_inventori"=>$kode_inventori,
"harga" => $_POST['harga_jual'][$key],
"diskon" => $_POST['diskon'][$key]
);
}
$res = $this->db->insert_batch('harga_inventori', $result);
redirect("inventori");
But when I'm using the same pattern for the updating function, it's not working at all.
for($i = 0; $i < count($_POST['harga_jual'][$i]); $i++) {
if($_POST['kode_kategori_pelanggan'][$i] != '') {
$res[] = array(
'harga' => $_POST['harga_jual'][$i],
'diskon' => $_POST['diskon'][$i],
);
$this->db->where('kode_inventori',$_POST['kode_inventori']);
$this->db->where('kode_kategori_pelanggan',$_POST['kode_kategori_pelanggan'][$i]);
$this->db->update('harga_inventori',$res);
}
}
redirect("inventori");
I'm trying the update_batch() but I got many errors, so I'm using for loop and updating a single row at a time.
What could be the problem here?
Its only a typo. You should pass the array $res not $data, and change $res[] to $res since it is not needed. You should also check with isset() to prevent errors of undefined:
for($i = 0; $i < count($_POST['harga_jual'][$i]); $i++) {
if(isset($_POST['kode_kategori_pelanggan'][$i])) {
$res = array(
'harga' => $_POST['harga_jual'][$i],
'diskon' => $_POST['diskon'][$i],
);
$this->db->where('kode_inventori',$_POST['kode_inventori']);
$this->db->where('kode_kategori_pelanggan',$_POST['kode_kategori_pelanggan'][$i]);
$this->db->update('harga_inventori',$res);
}
}
redirect("inventori");
It would help to see some of your data to know what you are trying to do. It seems a little strange that you initiate the counter $i at the same time using it as an array key in the for loop like this: for($i = 0; $i < count($_POST['harga_jual'][$i]); $i++)
It would help to know how the data in your $_POST looks like. You could try to remove the [$i] in your for loop. I would also check each POST variable it they are set before using them, something like:
for($i = 0; $i < count($_POST['harga_jual']); $i++) {
if(isset($_POST['kode_kategori_pelanggan'][$i])) {
// CHECK IF POST VARIABLES IS SET AND IF NOT SET A DEFAULT VALUE (IN THIS EXAMPLE AN EMPTY STRING):
$harga_jual = isset($_POST['harga_jual'][$i]) ? $_POST['harga_jual'][$i] : '';
$diskon = isset($_POST['diskon'][$i]) ? $_POST['diskon'][$i] : '';
$kode_inventori = isset($_POST['kode_inventori']) ? $_POST['kode_inventori'] : '';
$kode_kategori_pelanggan = $_POST['kode_kategori_pelanggan'][$i]; // ALREADY CHECKED ISSET ABOVE...
$data = array(
'harga' => $harga_jual,
'diskon' => $diskon,
);
$this->db->where('kode_inventori',$kode_inventori);
$this->db->where('kode_kategori_pelanggan', $kode_kategori_pelanggan);
$this->db->update('harga_inventori', $data);
}
}
redirect("inventori");

How to make a tree from a flat array - php

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.

Categories