Grab rows and then cells from a table - php

I'm using the Simple HTML Dom Parser to grab a table (in the image) and then grab each tr. This outputs all the items in the row as one string.
$contents = $html->find('div[class=product-table]', 0);
$titles = $contents->find('tr');
How can I create an array that keeps the data in rows but also allows me to output the individual cells? I want to be able to say there's 7 cells in a row (this could be flexible) and be able to output each individual cell in the row as variables (I need to do other stuff with these).
// Product Code Titles
$contents = $html->find('div[class=product-table]', 0);
$data = array();
$rows = $contents->find('tr');
$counter = 1;
foreach ($rows as $key_row => $row) {
// process rows here
foreach ($row->find('td') as $key_cell => $cell) {
$field_key = "field_5ae0882f9d6f9";
$data[] = array(
"column_title" => strip_tags($cell->innertext),
);
$counter++;
// process each cell on the current row iteration
// or whatever you need to do in each cell (calculations and whatnot)
// $data[] = then push it inside an array (you can prolly use the keys and use it in `$data`)
}
} ?>
<pre>
<?php print_r($data); ?>
</pre>
<?php update_field( $field_key, $data, $post_id );

Just like what I've said in the comments, treat the first loop for the rows, and for each row, another foreach for each cell. So basically you need two.
There's not much to go on since you don't have a sample markup, but here's the idea:
$data = array();
$rows = $contents->find('tr');
foreach ($rows as $key_row => $row) {
// process rows here
foreach ($row->find('td') as $key_cell => $cell) {
// process each cell on the current row iteration
echo $cell->innertext;
// or whatever you need to do in each cell (calculations and whatnot)
// $data[] = then push it inside an array (you can prolly use the keys and use it in `$data`)
}
}
Sidenote: Take note, if you want the header to be skipped, just use a counter and an if condition with continue, then you're good to go.

Related

looping an array, only do something when an attribute of the loop changes

In an foreach loop I am doing, I am building an array of URLS, I want to build this add to this array of urls every loop and then do something with that new array when attribute on the loop changes....for example, I am looping a dataset that contains an URL and a post_id, I want to keep adding URLS to a new array until the post id changes at which point I want save the new array (I can do this logic) and clear out the new array to be used again.
At the moment I have,
$new_array = [];
foreach ($results as $result) {
$new_array[] = $result->url;
$curr_id = $result->post_id;
if($curr_id != $result->post_id) {
$new_array = [];
}
}
My attempt above I always feel with return false as $curr_id will always equal the $result->post_id, but I don't know where else I could set it to watch for a change.
Maybe I misunderstood but perhaps like so:
$new_array = [];
$out=[]; // store urls here when id changes
$curr_id=-1; // create a value you know will not be viable
foreach( $results as $result ) {
/* will be invoked on 1st iteration and subsequent iterations when post_id changes */
if( $curr_id != $result->post_id ) {
/* change the var to new post_id */
$curr_id = $result->post_id;
/* if the array is not empty at this point, save it to output array */
if( !empty( $new_array ) )$out[]=$new_array;
/* create new array to store urls */
$new_array = [];
}
$new_array[] = $result->url;
}

Fill array with contents of csv with php

I am trying to fill a array with a csv so each field is separate part of the array, when i have filled the array and echo it out it quite literally says array for every enter.
I have a feeling that once i sort the csvfull array that the sku might need to be in loop inside the main processing loop to.
$ocuk = fopen("ocuk.csv", "r");
while (($result = fgetcsv($ocuk)) !== false)
{
$csvfull[] = $result;
}
print_r ($csvfull[0][1]);
$sku="$csvfull[1]";
while (($csv = fgetcsv($ocuk)) !== FALSE)
{
if (false === empty(array_intersect($sku, $csv)))
{
code to display the results from csv that match the $sku variable
}
}
What i need it to do is csvfull array to fill with the contents of the csv such i can then call it into the variable sku to do comparison in next part of the code.
EDIT example of what i mean
csv example
data,data2,data3,data4 etc
data10,data20,data30,data40 etc
the array would then be like this
$csvfull=array() would contain the below
array("data","data2","data3","data4");
array("data10","data20","data30","data40");
then when i call csvfull[1] it display data2 then would go onto data 20 etc
$csvfull is a 2-dimensional array. The first dimension is the rows of the CSV, the second dimension is the columns. So $csvfull[1] is an array containing all the values from the second line of the file. To get the SKU, you need to drill down to the appropriate column, e.g.
foreach ($csvfull as $row) {
$sku = $row[1];
// Do something with $sku
}
If you want to get an array of all the SKUs, you can do:
$sku = array();
foreach ($csvfull as $row) {
$sku[] = $row[1];
}
try like this:
<?php
$ocuk = fopen('clientes.csv','r');
$i=0;
while(!feof($ocuk)){
$values = fgetcsv($ocuk);
if(empty($values[1] )){ // any index which is not empty to make sure that you are reading valid row.
continue;}
$csvfull[$i] = $values;
$i++;
}
print_r($csvfull);
.
fclose($ocuk);

Flatten RecursiveIteratorIterator array by children

I can't seem to figure out the best way to do this. I have a RecursiveIteratorIterator.
$info = new RecursiveIteratorIterator(
new GroupIterator($X), # This is a class that implements RecursiveIterator
RecursiveIteratorIterator::SELF_FIRST
);
Note: GroupIterator is a class that handles our custom formatted data
When I loop through it, I get exactly what I expect.
foreach($info as $data){
echo $info->getDepth().'-'.$data."\n";
}
The output is:
0-a
1-b
2-c
2-d
1-e
2-f
0-g
1-h
2-i
This is correct, so far. Now, what I want is to flatten the parents and children into a single array. I want one row for each max-depth child. The output I am trying to get is:
0-a 1-b 2-c
0-a 1-b 2-d
0-a 1-e 2-f
0-g 1-h 2-i
I can't figure out how to do this. Each iteration over the loop gives me another row, how can I combine the rows together that I want?
I managed to figure it out. #ComFreek pointed me in the right direction. Instead of using a counter, I used the current depth to check when I hit the lowest child, then I added the data to the final array, otherwise I added it to a temp array.
$finalArray = array();
$maxDepth = 2;
foreach($info as $data){
$currentDepth = $info->getDepth();
// Reset values for next parent
if($currentDepth === 0){
$currentRow = array();
}
// Add values for this depth
$currentRow[$currentDepth] = $data;
// When at lowest child, add to final array
if($currentDepth === $maxDepth){
$finalArray[] = $currentRow;
}
}
Try adding a counter variable:
// rowNr loops through 0, 1, 2
$rowNr = 0;
$curData = [];
$outputData = [];
foreach($info as $data){
// got last element, add the temp data to the actual array
// and reset temp array and counter
if ($rowNr == 2) {
$outputData[] = $curData;
$curData = [];
$rowNr == 0;
}
else {
// save temp data
$curData[] = $info->getDepth() . '-' . $data;
}
$rowNr++;
}

Inserting Values into Array

I Select * From my sql table in PHP, and I convert it to JSON, so the results are like this:
([
{"id":"350","Name":"BlaBla","Info":"BlaBla"},
{"id":"351","Name":"BlaBla","Info":"BlaBla"},
{"id":"352","Name":"BlaBla","Info":"BlaBla"}
]);
I scrape a clients website for images (this is a request of the client) based on the id in the records above, and I output images into a similar array/dictionary and output into JSON:
([
{"image1":"http://Sourceofimg.jpg"},
{"image2":"http://Sourceofimg.jpg"},
{"image3":"http://Sourceofimg.jpg"},
{"image4":"http://Sourceofimg.jpg"},
{"image5":"http://Sourceofimg.jpg"}
]);
So lets say I scrape a page, page.php?id=350, I'd get a similar output to the image array above, how can I append/add that result to the first array where id=350?
EDIT
This is where I would like to combine the arrays:
while ($row = mysql_fetch_assoc($results))
{
$rows[] = $row;
$url = 'http://www.url.com/page.php?id='.$row['id'].'';
$html = file_get_html($url);
foreach($html->find('div.classvalue') as $element){
foreach($element->find('img') as $img){
$images[] = array("image".$i."" => $img->src);
$i = $i + 1;
$rows = array_merge($rows, $images);
} } }
My version clearly does not work, it seems to be appending new images to the already existing image[] therefore the last element of $rows[] will get the full list of images, where I just want the images tied in with that id.
Also by merging, it does not merge correctly I get an output like this e.g:
([
{"id":"350","Name":"BlaBla","Info":"BlaBla"},
{"image1":"http://Sourceofimg.jpg"},
{"image2":"http://Sourceofimg.jpg"},
{"id":"351","Name":"BlaBla","Info":"BlaBla"}
]);
I would like it like:
([
{"id":"350","Name":"BlaBla","Info":"BlaBla", "image1":"http://Sourceofimg.jpg", "image2":"http://Sourceofimg.jpg"} etc...
]);
I think this is what you need. You first have to start with a clean $images array using $images = array(); so you won't have the results of previous loops in your array. Then you should collect the images inside the $images array (using the forloops). Then you can store the images in the $row array under the key 'images' using $row['images'] = $images;.
Hope this is what you need.
while ($row = mysql_fetch_assoc($results)) {
$url = 'http://www.url.com/page.php?id='.$row['id'].'';
$html = file_get_html($url);
$images = array();
$i = 0;
foreach($html->find('div.classvalue') as $element){
foreach($element->find('img') as $img){
$row["image".$i] = $img->src;
$i = $i + 1;
}
}
$rows[] = $row;
}
On php side use array_merge() with both arrays. In addition array_unique will become handy (it will remove duplicates).
You have to add $images to the actual row. What you are doing, is resizing array.
$actualIndex = count($rows);
$rows[] = $row;
...
...
$rows[$actualIndex] = $images;
Or something like this
You can tweak $rows[$actualIndex] to satisfy your structure.
First set somewhere $imageID = 1;
$rows[$actualIndex]['image'.$imageID] = $images['url']
imageID++;

shift array without indexOfOutBounds

I have 2 array's with the same length. array $gPositionStudents and array $gPositionInternships. Each student is assigned to a different internship, That part works.
Now I want the first element (index 0) of $gPositionStudent refer to the second (index 1) element of array $gPositionInternship. That implicitly means that the last element of $gPositionStudents refer to the first element of $gPositionInternship. (I included a picture of my explanation).
My Code is:
// Make table
$header = array();
$header[] = array('data' => 'UGentID');
$header[] = array('data' => 'Internships');
// this big array will contains all rows
// global variables.
global $gStartPositionStudents;
global $gStartPositionInternships;
//var_dump($gStartPositionInternships);
$rows = array();
$i = 0;
foreach($gStartPositionStudents as $value) {
foreach($gStartPositionInternships as $value2) {
// each loop will add a row here.
$row = array();
// build the row
$row[] = array('data' => $value[0]['value']);
//if($value[0] != 0 || $value[0] == 0) {
$row[] = array('data' => $gStartPositionInternships[$i]);
}
$i++;
// add the row to the "big row data (contains all rows)
$rows[] = array('data' => $row);
}
$output = theme('table', $header, $rows);
return $output;
Now I want that I can choose how many times, we can shift. 1 shift or 2 or more shifts. What I want exists in PHP?
Something like this:
//get the array keys for the interns and students...
$intern_keys = array_keys($gStartPositionInternships);
$student_keys = array_keys($gStartPositionStudents);
//drop the last intern key off the end and pin it to the front.
array_unshift($intern_keys, array_pop($intern_keys));
//create a mapping array to join the two arrays together.
$student_to_intern_mapping = array();
foreach($student_keys as $key=>$value) {
$student_to_intern_mapping[$value] = $intern_keys[$key];
}
You'll need to modify it to suit the rest of your code, but hopefully this will demonstrate a technique you could use. Note the key line here is the one which does array_unshift() with array_pop(). The comment in the code should explain what it's doing.
I think you want to do array_slice($gPositionsStudents, 0, X) where X is the number of moves to shift. This slices of a number of array elements. Then do array_merge($gPositionsStudents, $arrayOfSlicedOfPositions); to append these to the end of the original array.
Then you can do an array_combine to create one array with key=>value pairs from both arrays.

Categories