Counting blank spaces till next string in PHP array - php

I have imported .xlsx file to PHP through a script. I only need two columns from the file
This is done, but as you can see there is address and following it blank spaces.
I need the information from right column to be in one string corresponding to the address on the left.
foreach ($Reader as $Row)
{
array_push($data, $Row);
$aadress_loc = array_search("Aadress", $Row);
$eluruumid = array_search("Ehitise osad", $Row);
array_push($asukohtruumid, $aadress_loc);
array_push($asukohtruumid, $eluruumid);
}
$li_length = count($data);
for ($i = 1; $i < $li_length; $i++){
array_push($aadress_mas,($data[$i][$asukohtruumid[0]])); // left column
array_push($ruumid_mas,($data[$i][$asukohtruumid[1]])); // right column
}
Array
(
[0] => Harju maakond, Kernu vald, Laitse küla, Lossi tee 6
[1] =>
[2] => // 0;2 is the length of the first element
)
Array
(
[0] => E/1;E/2;E/3;E/4;E/5;E/6;M/7/Kontoriruumid;E/8;E/9
[1] => E/10;E/11;E/12;E/13;E/14;E/15;E/16;E/17;E/18;E/19
[2] => E/20;E/21;E/22;E/23;E/24
so I need to merge these 0;2 elements from another array to one string
and repeat the process with another elements from aadress array.
Here is the array with the diffrences but I don't know how can I use it to do what I need.
Sorry for not so good english.

Hopefully I understand the question but I think you are looking for this:
foreach ($Reader as $Row)
{
echo $row[0].' - '.$row[7];
// OR
echo $row['Aadress'].' - '.$row['Ehitise osad'];
}
I am not sure which one will work in your situation.

Related

PHP Aligning multiple arrays of different lengths

I'm probably just overlooking the obvious but I'd like to blame it on the fact that I'm new to PHP.
I have some number of arrays being returned with similar information but differing amounts of it.
I'll put some example arrays below:
(t1-s1-1=1, t1-s1-2=1, t1-s2-1=1, t1-s2-2=1)
(t2-s1-1=1, t2-s2-1=2, t2-s2-2=1)
(t3-s1-1=1, t3-s2-1=1, t3-s3-1=1, t3-s3-2=3)
So I would like to make a table out of this information. Something like this:
test .. s1-1 .. s1-2 .. s2-1 .. s2-2 .. s3-1 .. s3-2
t1 ........1 .....1 ..........1 ....... 1.........1..........1
t2 ........1 .......X..........1..........1........1..........1
t3 ........1 .......X..........1..........X........1..........1
( where x is something that wasn't there. )
So every array has an s1 but could have s1-1, s1-2, s1-3 or simply s1-1. That creates very different sized arrays.
The problem is that each array can have wildly different information and because they are Indexed arrays instead of Associative arrays I'm not sure how to best equalize them. I can't consistently say index 3 is s1-3 or something else.
I can't just loop through manually because I never know where a gap will appear. I can't look for specific indexes because the arrays aren't associative so the titles are built into the value and I don't know how to access them separately.
Any good ideas out there that maybe a newbie is overlooking? I'm open to non-tabular display ideas as well as long as I can easily sort and display the information.
Thanks
I'm assuming your original arrays contain values as string, so for instance, in PHP syntax, they look like:
['t1-s1-1=1', 't1-s1-2=1', 't1-s2-1=1', 't1-s2-2=1']
Basically, you should create a bi-dimensional array:
go through all arrays and by using a regex extract the different parts, that is, for the first element in the array above: t1 (the index for the first level in the bi-dimensional array), s1-1 (the index for the second level in the bi-dimensional array) and the value 1
insert the value in the bi-dimensional array
keep in a separate array, let's call it allColumns every second index above (sx-y), even you will have duplicate values you can, at the end, delete those duplicate and order it alphabetically
After that, you will have all the value in the bi-dimensional array but you still miss the gaps, so what you can do it iterate over the bi-dimensional array, and for every dimension tz (t1, t2,...), go through for all the values stored in allColumns and if you don't find the entry for that sx-y in the bi-dimensional array for that tz, add it with value x (or probably with value = 0)
I think an example can clarify the above:
// arrays of arrays, I don't know how you receive the data
$arrays = [
['t1-s1-1=1', 't1-s1-2=1', 't1-s2-1=1', 't1-s2-2=1'],
['t2-s1-1=1', 't2-s2-1=2', 't2-s2-2=1'],
['t3-s1-1=1', 't3-s2-1=1', 't3-s3-1=1', 't3-s3-2=3']
];
// bi-dimensional array
$output = [];
// it will store all columns you find in the $arrays entry
$allColumns = [];
// iterate for every array you receive, i.e. ['t1-s1-1=1', 't1-s1-2=1', 't1-s2-1=1', 't1-s2-2=1']
foreach ($arrays as $array) {
// iterate over every element in the array: 't1-s1-1=1', 't1-s1-2=1', 't1-s2-1=1' and 't1-s2-2=1'
foreach ($array as $item) {
// extract the parts on every element: $matches is an array containing the different parts
preg_match('/^(t\d+)-(s\d+-\d+)=(\d+)/', $item, $matches);
/**
* $matches[0] would contains the element if matched: 't1-s1-1=1'
* $matches[1] would contains 't1' if matched
* $matches[2] would contains 's1-1' if matched
* $matches[2] would contains 1 (integer) if matched
*/
if (!empty($matches)) {
$output[$matches[1]][$matches[2]] = $matches[3];
$allColumns[] = $matches[2];
}
}
}
// clean duplicates
$allColumns = array_unique($allColumns);
// sort values alphabetically
sort($allColumns);
// iterate over the just created bi-dimensional array
foreach ($output as $row => $columns) {
// iterate for all columns collected before
foreach ($allColumns as $column) {
// if one of column in 'allColumns' doesn't exit in $output you added in the correct place adding a zero value
if (!in_array($column, array_keys($columns))) {
$output[$row][$column] = 0;
}
}
}
To print the output you should only iterate over $ouput
This will be the array internally:
(
[t1] => Array
(
[s1-1] => 1
[s1-2] => 1
[s2-1] => 1
[s2-2] => 1
[s3-1] => 0
[s3-2] => 0
)
[t2] => Array
(
[s1-1] => 1
[s2-1] => 2
[s2-2] => 1
[s1-2] => 0
[s3-1] => 0
[s3-2] => 0
)
[t3] => Array
(
[s1-1] => 1
[s2-1] => 1
[s3-1] => 1
[s3-2] => 3
[s1-2] => 0
[s2-2] => 0
)
)
It exists other ways to implement the above, like skip the step where you fill the gaps and do it on the fly, ...
Updated
The simplest way to display the results in a HTML page is by embedding a php script to iterate over the associative array and compose the HTML table (I encourage you to study and research MVC to separate logic from the view)
<!DOCTYPE html>
<?php
// arrays of arrays, I don't know how you receive the data
$arrays = [
['t1-s1-1=1', 't1-s1-2=1', 't1-s2-1=1', 't1-s2-2=1'],
['t2-s1-1=1', 't2-s2-1=2', 't2-s2-2=1'],
['t3-s1-1=1', 't3-s2-1=1', 't3-s3-1=1', 't3-s3-2=3']
];
// bi-dimensional array
$output = [];
// it will store all columns you find in the $arrays entry
$allColumns = [];
// iterate for every array you receive, i.e. ['t1-s1-1=1', 't1-s1-2=1', 't1-s2-1=1', 't1-s2-2=1']
foreach ($arrays as $array) {
// iterate over every element in the array: 't1-s1-1=1', 't1-s1-2=1', 't1-s2-1=1' and 't1-s2-2=1'
foreach ($array as $item) {
// extract the parts on every element: $matches is an array containing the different parts
preg_match('/^(t\d+)-(s\d+-\d+)=(\d+)/', $item, $matches);
/**
* $matches[0] would contains the element if matched: 't1-s1-1=1'
* $matches[1] would contains 't1' if matched
* $matches[2] would contains 's1-1' if matched
* $matches[2] would contains 1 (integer) if matched
*/
if (!empty($matches)) {
$output[$matches[1]][$matches[2]] = $matches[3];
$allColumns[] = $matches[2];
}
}
}
// clean duplicates
$allColumns = array_unique($allColumns);
// sort values alphabetically
sort($allColumns);
// iterate over the just created bi-dimensional array
foreach ($output as $row => $columns) {
// iterate for all columns collected before
foreach ($allColumns as $column) {
// if one of column in 'allColumns' doesn't exit in $output you added in the correct place adding a zero value
if (!in_array($column, array_keys($columns))) {
$output[$row][$column] = 0;
}
}
}
?>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Table Page</title>
</head>
<body>
<table>
<thead>
<?php
echo '<tr><th>Test</th>';
foreach ($allColumns as $head) {
echo sprintf('<th>%s</th>', $head);
}
echo '</tr>';
?>
</thead>
<tbody>
<?php
foreach ($output as $key => $columns) {
echo sprintf('<tr><td>%s</td>', $key);
foreach ($columns as $column) {
echo sprintf('<td>%s</td>', $column);
}
echo '</tr>';
}
?>
</tbody>
</table>
</body>
</html>
Try the following:
$final_array = array();
$temp_array = array();
foreach ($t1 as $t) {
$isin = 0;
$expression = substr($t, 0, strpos($t, "="));
$expression = str_replace("t1-", "" , $expression)
$value = substr($t, strpos($t, "=") + 1);
for ($i = 0; $i < 3; $i++) {
foreach ($x = 0; $x < 3; $x++) {
if ($expression == "s{$i}-{$x}") {
$isin = 1;
array_push($temp_array, $value);
}
}
}
if ($isin == 0) { array_push($temp_array, "X"); }
}
array_push($final_array, $temp_array);
It's not a great solution because you're choosing to do this in a really odd way but you should see the gist of what how to get what you want from this example.

Reading data from a text file using Strpos & Substr to remove commas between and a while loop to repeat for each row

I'll try and be as clear as I can with what my problem is here, I've been working on this one for a while now and can't seem to get my head around it. Basically, I'm trying to:
Read numbers from a text file & store them in a 2D array
Remove any commas in the text file and store the remaining data in a table format
Using strpos & substr to extract the data, leaving behind unwanted commas
Then using a while loop to repeat this process so every line in the text file is read one at a time until all the lines are read.
At first my code was stating what lines I had errors in and I have since amended but now the php page doesnt seem to load at all. Is there some sort of error within my while loop statement?
Here is the php code I'm currently working with that doesnt seem to be loading:
$fileopen = fopen($file,'r') or die("Sorry, cannot find the file $file");
if($fileopen){
while (($buffer=fgets($fileopen,4096))!==false){
}
if(!feof($fileopen)){
echo "Error:unexpected fgets() fail\n";
}
fclose($fileopen);
}
$filearray = array();
$rows = 0;
$columns = 0;
$fileopen = fopen($file,'r') or die("Sorry, cannot open $file");
while(!feof($fileopen))
{
$line = fgets($fileopen);
$length = strlen($line);
$pos = 0;
$comma = 0;
while($pos < length) {
$comma = strpos($line,",",$comma);
$filearray[$rows][$columns] = substr($line,$pos,$comma);
$pos = $comma +1;
$columns++;
}
$columns = 0;
$rows++;
}
This section is essentially displaying the extracted data from the text file in a table format:
function array_transpose($filearray)
{
array_unshift($filearray, NULL);
return call_user_func_array('array_map', $filearray);
}
echo"<h1></h1>";
echo "<table border = 0 >";
for($row=0; $row<$count; $row++){
print "<tr>";
for($col=0; $col<$count; $col++){
echo "<td>".$array[$row][$col]."</td>";
}
}
echo "</table>";
It was quite the challenge for me to get this one to work, but I managed to do it. I've put comments inside the code to explain what's happening. The reasons it didn't work for you (as I said in the comments) was because you were creating an infinite loop. The $pos integer was always smaller than your $length integer. So the while() loop would never break.
Another issue that you didn't encounter yet was the use of $comma as the length for substr(). Because strpos() returns you the actual position and not the position relative to the offset, this would cause problems. That's why you needed to save the previous position of the delimiter (comma) and substract that from the current position of the delimiter.
Anyway, here is my example code. It's giving you the result that you need. It's up to you to incorporate it into your own code.
<?php
// Initial variables
$result = array();
$key = 0;
// Open the file
$handle = fopen("numbers.txt", "r");
if ($handle) {
while (($line = fgets($handle)) !== false) {
// First we set the delimiter into a variable
$delimiter = ',';
// Some integers we're going to use for our loop
$pos = 0; // The current position
$comma = 0; // Position of the next comma
$innerkey = 0; // Key used for the 2D result array
$previous = 0; // Previous comma position
$loops = 0; // Number of loops
$nr_commas = substr_count($line, $delimiter); // Number of commas in a single line
while($loops <= $nr_commas) {
// Get the position of the next comma
$comma = strpos($line,$delimiter,$comma);
// Make sure a comma is found
if($comma !== false){
// Put the substring into the result array using $pos as the offset
// and calculating the length by substracting the position of the previous
// comma from the current comma.
$result[$key][$innerkey] = substr($line,$pos,$comma - $previous);
// Add 1 to the previous comma or it will include the current comma in the result
$previous = $comma + 1;
$pos = $comma + 1;
$innerkey++;
$loops++;
$comma++;
} else {
// In case no more commas are found, we still need to add the last integer
$loops++;
$result[$key][$innerkey] = substr($line,strrpos($line,$delimiter)+1);
}
}
$key++;
}
fclose($handle);
} else {
echo "Unable to open the file";
}
echo "<pre>";
print_r($result);
echo "</pre>";
?>
TXT File used:
3,34,2,35,4,234,34,2,53,4
5,4,23,6,67,324,5,34,5
345,67,3,45,6,7
Result:
Array
(
[0] => Array
(
[0] => 3
[1] => 34
[2] => 2
[3] => 35
[4] => 4
[5] => 234
[6] => 34
[7] => 2
[8] => 53
[9] => 4
)
[1] => Array
(
[0] => 5
[1] => 4
[2] => 23
[3] => 6
[4] => 67
[5] => 324
[6] => 5
[7] => 34
[8] => 5
)
[2] => Array
(
[0] => 345
[1] => 67
[2] => 3
[3] => 45
[4] => 6
[5] => 7
)
)

Handle csv with php in for loop and write them back

i'm struggling with a php code that must open more than 1 csv, handle its content and write back on a different way that was initially.
So, i have all csv's on rows, and i wanna parse them and split them in columns on 2 rows.
The code looks like:
$currentDirOtherCSV = __DIR__ . "/uploads/" . $ftp_location . "partial_crawler_data/";
$files_other_CSV = scandir($partial_crawler_data, 1);
for($i = 0; $i < count($files_other_CSV) - 2; $i++){
$csvFileToOpen = file($currentDirOtherCSV . $files_other_CSV[$i]);
$screamingDataFirst = [];
foreach ($csvFileToOpen as $line) {
$screamingDataFirst[] = str_getcsv($line);
}
// remove header from csv
array_shift($screamingDataFirst);
array_shift($screamingDataFirst);
// handle array to export it on 2 rows
$theExportArray = [[],[]];
for($j = 0; $j < count($screamingDataFirst); $j++){
if(!array_key_exists('1', $screamingDataFirst[$j])) {
$screamingDataFirst[$j][1] = "";
}
}
foreach ($screamingDataFirst as $key => $row){
$theExportArray[0][$key] = $row[0];
$theExportArray[1][$key] = $row[1];
}
print_r($theExportArray);
// edit csv file remote
$new_csv_data = fopen($currentDirOtherCSV . $files_other_CSV[$i], "w");
foreach($theExportArray as $row){
fputcsv($new_csv_data, $row, ";");
}
fclose($new_csv_data);
}
The csv looks like:
"Page Titles - Duplicate"
"Address","Title 1"
"http://www.seloo.ro/index.php?route=product/product&path=60&product_id=123","Scaun tapitat Alb"
"http://www.seloo.ro/index.php?route=product/product&path=60&product_id=122","Scaun tapitat Alb"
"http://www.seloo.ro/index.php?route=product/product&path=60&product_id=121","Scaun tapitat Alb"
"http://www.seloo.ro/index.php?route=product/product&path=60&product_id=127","Scaun tapitat Alb"
so i get this array by parsing it:
Array
(
[0] => Array
(
[0] => http://www.seloo.ro/index.php?route=product/product&path=60&product_id=123
[1] => http://www.seloo.ro/index.php?route=product/product&path=60&product_id=122
[2] => http://www.seloo.ro/index.php?route=product/product&path=60&product_id=121
[3] => http://www.seloo.ro/index.php?route=product/product&path=60&product_id=127
)
[1] => Array
(
[0] => Scaun tapitat Alb
[1] => Scaun tapitat Alb
[2] => Scaun tapitat Alb
[3] => Scaun tapitat Alb
)
)
EDIT
That must be:
http://www.seloo.ro/index.php?route=product/product&product_id=95;http://www.seloo.ro/index.php?route=product/product&path=59&product_id=95;http://www.seloo.ro/index.php?route=product/product&product_id=94;
"Masa New vision";"Masa flori lila";"Masa flori lila";
Problem:
I thought that if i open the file, handle it, push it back modified in the csv and close (fclose) then do it again untill no csv, will handle them 1 by one...
But it only write in a single csv, rest of them arent touched
Am i missing something?
UPDATE
The script works fine.
The problem was that i have tried to update the unuploaded files on the server.
Script was faster than upload.
Thank you all and sorry, i should check that earlier

Parsing two files, and comparing strings

So I have two files, formatted like this:
First file
adam 20 male
ben 21 male
Second file
adam blonde
adam white
ben blonde
What I would like to do, is use the instance of adam in the first file, and search for it in the second file and print out the attributes.
Data is seperated by tab "\t", so this is what I have so far.
$firstFile = fopen("file1", "rb"); //opens first file
$i=0;
$k=0;
while (!feof($firstFile) ) { //feof = while not end of file
$firstFileRow = fgets($firstFile); //fgets gets line
$parts = explode("\t", $firstFileRow); //splits line into 3 strings using tab delimiter
$secondFile= fopen("file2", "rb");
$countRow = count($secondFile); //count rows in second file
while ($i<= $countRow){ //while the file still has rows to search
$row = fgets($firstFile); //gets whole row
$parts2 = explode("\t", $row);
if ($parts[0] ==$parts2[0]){
print $parts[0]. " has " . $parts2[1]. "<br>" ; //prints out the 3 parts
$i++;
}
}
}
I cant figure out how to loop through the second file, get each row, and compare to the first file.
You have a typo in the inner loop, you are reading firstfile and should be reading second file. In addition, after exiting inner loop you would want to re-wind the secondfile pointer back to the beginning.
How about this:
function file2array($filename) {
$file = file($filename);
$result = array();
foreach ($file as $line) {
$attributes = explode("\t", $line);
foreach (array_slice($attributes, 1) as $attribute)
$result[$attributes[0]][] = $attribute;
}
return $result;
}
$a1 = file2array("file1");
$a2 = file2array("file2");
print_r(array_merge_recursive($a1, $a2));
It will ouput the following:
Array (
[adam] => Array (
[0] => 20
[1] => male
[2] => blonde
[3] => white
)
[ben] => Array (
[0] => 21
[1] => male
[2] => blonde
)
)
However this one reads both files in one piece and will crash, if they are large ( >100MB). On the other hand 90% of all php programs have this problem, since file() is popular :-)

Get next from array in a loop

i am so stuck , please someone help if you have 2 min.
i have a foreach where I get values from session something like
foreach ($result as $i => $item ) {
$values_array = explode("\n",$get_widths); // outputs Array ( [0] => 120 [1] => 180)
// here I need to echo the value from the array but only ONCE
}
the issue is that this is used by 2 or more items and array outputs gets repeated every time , so if 2 items i get
Array ( [0] => 120 [1] => 180) Array ( [0] => 120 [1] => 180) or
120 120
instead
120 180
for actual code see here
<?php
foreach ($list as $i => &$item){
$i=0;
$is_group = $item_params->get('is_group');
$group_widths = $item_params->get('group_widths');
$group_widths_array = explode("\n",$group_widths);
if($is_group == 1){
echo $group_widths_array[$i];
}
}
?>
please note I cant move outside the foreach. thank you
I would simply use a flag variable of some sort to determine if we have processed yet or not.
$values_array = explode("\n",$get_widths);
if (!isset($we_have_outputted)) {
echo '<pre>'. print_r($values_array, true) .'</pre>';
$we_have_outputted = true;
}
I am completely missing the point of this loop...
You are iterating over an array, assigning the key to $i and the value to $item but then you set $i to 0, echoing $group_widths_array[0] every time your condition is met and $item you don´t use at all...
That can´t be right, can it?
Anyway, it seems to me that the reason that your output is repeated is that you output $group_widths_array[0] every time and $is_group is the same on every iteration.

Categories