After all I'm sorry for my English.
I'm writing a script in PHP and I encountered a small problem.
The idea is to create an array per line of text and replace the fourth value with a string representing the status.
I have a line of text e.g.
2022,33422,0,1,0,22
With a single line it works to create the array, but with multiple lines it creates an unexpected result.
Example:
2022,33422,0,1,0,22
2024,3232,01,1,04,298762
$myArray = explode(',', $uploadServer);
$status = array(0 => "Unprocessed",
1 => "Processing",
2 => "Download aborted because the file became too big.",
3 => "Download aborted because the file downloaded too long.",
4 => "Download finished. Uploading to RapidShare.",
5 => "Upload to RapidShare finished. Job finished.",
7 => "Upload failed 3 times for unknown reasons. Job aborted.",
8 => "Upload failed because the file is black listed.",
9 => "Download failed for unknown reasons.",
11 => "Enqueued for later processing because this account already downloads 5 files at the same time.");
foreach ($myArray as $valor) {
if(array_key_exists($valor[3],$status)) {
return $passer[] = $status[$valor[3]];
} else {
return FALSE;
}
}
The result of $myArray is
Array
(
[0] => 2022
[1] => 33422
[2] => 0
[3] => 1
[4] => 0
[5] => 22
)
But I need this final array
Array
(
[0]=>array(
[0] => 2022
[1] => 33422
[2] => 0
[3] => Processing
[4] => 0
[5] => 22
)
[1]=>array(
[0] => 2022
[1] => 33422
[2] => 0
[3] => Processing
[4] => 0
[5] => 22
)
)
Any idea?
thanks
UPDATE: So you have a string with a linebreak in it. This linebreak is an invisible character (\n). First split your string on every linebreak. Then loop through this array. split the strings on every comma and change the value with index 3:
$myArray = explode("\n", $uploadServer);
$status = array(0 => "Unprocessed",
1 => "Processing",
2 => "Download aborted because the file became too big.",
3 => "Download aborted because the file downloaded too long.",
4 => "Download finished. Uploading to RapidShare.",
5 => "Upload to RapidShare finished. Job finished.",
7 => "Upload failed 3 times for unknown reasons. Job aborted.",
8 => "Upload failed because the file is black listed.",
9 => "Download failed for unknown reasons.",
11 => "Enqueued for later processing because this account already downloads 5 files at the same time.");
$passer = array(); //create array to fill
foreach( $myArray as $valor ) { //loop through lines
if( !empty($valor) ) { // check for empty line
$tmp = explode(',', $valor); //make array of strings
if(array_key_exists($tmp[3],$status)) { //check value [3]
$tmp[3] = $status[$tmp[3]];
}
$passer[] = $tmp; //append array to parent array
}
}
if I understand you correctly, you are overthinking the solution.
foreach ($myArray as $valor) {
if(isset($status[$valor[3]])) { # this checks if there is a status with that index/key
return $passer[] = $status[$valor[3]];
} else {
return FALSE;
}
}
Related
My code
$str = array(fgets($da, 1024));
print_r($str);
I'm trying to create an array in php from a dynamic output , but i noticed the keys in all object are [0], i need to assign a diferent key number to each object, how can i do that ?
Looks weird to me that all keys are 0, im trying to figure but nothing helps me.
Result :
Array
(
[0] =>
)
Array
(
[0] => 200
)
Array
(
[0] => 819105 rs fs
)
Array
(
[0] => 300 tert
)
Array
(
[0] => THO
)
Array
(
[0] => 91362
)
Array
(
[0] =>
)
Array
(
[0] => 06-20-21 6:56 PM
)
Array
(
[0] =>
)
Array
(
[0] =>
Array
(
[0] => 3 Cat 20 4.82 0.0 7.4 30
)
Array
(
[0] => 4 Dogs 19 26.2 0.8 7.1 62
)
Array
(
[0] =>
)
Thanks
If the input is reliable, you can split on whitespace for example:
$str = fgets($da, 1024);
$a = explode(" ", $str);
print_r($a);
array_merge with the spread (...) operator would work.
$str = array(fgets($da, 1024));
$str = array_merge(...$str);
All of the keys appear to be zero because you are wrapping each line from the file in its own array, so each array has one element at index zero.
If you define a buffer outside of your read loop, and add each line to it, each line will have its own index.
$da = fopen('test.txt', 'r');
// Define a buffer for the output
$data = [];
while (($str = fgets($da)) !== false)
{
// Add our line to the buffer
$data[] = $str;
}
fclose($da);
print_r($data);
output:
Array
(
[0] => 200
[1] => 819105 rs fs
[2] => 300 tert
[3] => THO
[4] => 91362
[5] => 06-20-21 6:56 PM
[6] => 3 Cat 20 4.82 0.0 7.4 30
[7] => 4 Dogs 19 26.2 0.8 7.1 62
)
But it looks like you may have some sort of header information in the first 6 lines of the file, maybe info from an HTTP request? Then lines that are somehow delimited, maybe by tab, but then the text got munged somewhere on the way into the SO post?
You can use a combination of fgets and fgetcsv to pull the data from the file and organize it into associative arrays.
Input:
200
819105 rs fs
300 tert
THO
91362
06-20-21 6:56 PM
3 Cat 20 4.82 0.0 7.4 30
4 Dogs 19 26.2 0.8 7.1 62
5 Wombat 20 4.20 0.0 6.9 30
6 Hedgehogs 19 26.2 0.8 7.1 62
$da = fopen('test.txt', 'r');
// Define a buffer for the output
$data = [];
// Define the fields in the header, each header line needs an entry
$headerDef = [
'status',
'transfer_stats',
'what_is_this',
'something_else',
'content_length',
'timestamp'
];
// Define the columns in the data rows, each column needs an entry
$columnDef = [
'id',
'type',
'count',
'average_weight',
'tax',
'food_weight_percent_per_day',
'fluffiness'
];
// Define an array to hold the header contents
$headerData = [];
// For each line in the header definition, extract a line from the file
while (!empty($headerDef) && $str = fgets($da, 1024))
{
$currValue = trim($str);
// Pull the next field from the front of the array
$currHeaderField = array_shift($headerDef);
// Set the entry in the header data array
$headerData[$currHeaderField] = $currValue;
}
while ($row = fgetcsv($da, 1024, "\t"))
{
// Create a new associative array by combining the column names and the row data
$data[] = array_combine($columnDef, $row);
}
fclose($da);
print_r($headerData);
print_r($data);
output:
Array
(
[status] => 200
[transfer_stats] => 819105 rs fs
[what_is_this] => 300 tert
[something_else] => THO
[content_length] => 91362
[timestamp] => 06-20-21 6:56 PM
)
Array
(
[0] => Array
(
[id] => 3
[type] => Cat
[count] => 20
[average_weight] => 4.82
[tax] => 0.0
[food_weight_percent_per_day] => 7.4
[fluffiness] => 30
)
[1] => Array
(
[id] => 4
[type] => Dogs
[count] => 19
[average_weight] => 26.2
[tax] => 0.8
[food_weight_percent_per_day] => 7.1
[fluffiness] => 62
)
[2] => Array
(
[id] => 5
[type] => Wombat
[count] => 20
[average_weight] => 4.20
[tax] => 0.0
[food_weight_percent_per_day] => 6.9
[fluffiness] => 30
)
[3] => Array
(
[id] => 6
[type] => Hedgehogs
[count] => 19
[average_weight] => 26.2
[tax] => 0.8
[food_weight_percent_per_day] => 7.1
[fluffiness] => 62
)
)
Of course the field names are just made up, I have no idea what your actual data is. And I'm assuming that the data rows are delimited with tabs, that may not be the case. But you should be able to use this as a starting point.
PS. It could be that the HTTP data at the top of the file is included by mistake, perhaps from a curl request? You could change that with the CURLOPT_HEADER option and curl_setopt
I have a PHP that does some text manipulation saving the user input and gets this unix timestamps and also saves them on a text file and in the end the file looks like this:
1;0%;5%;4;1527085890;
1;15%;0%;1;1527085890;
1;20%;0%;2;1527085890;
2;5%;2%;3;1527085901;
2;20%;0%;1;1527085901;
2;2%;0%;2;1527085901;
3;2%;0%;5;1527085912;
3;20%;0%;1;1527085912;
3;3%;0%;2;1527085912;
Basically on the first three rows the timestamp in the end is the same, on the next three rows the timestamp in the end is the same etc. What I would like to get in the end of every line is to copy the second timestamp and append it to the first three rows, get the third timestamp and append it to the next three rows and so on. Finally to get this output:
1;0%;5%;4;1527085890;1527085901;
1;15%;0%;1;1527085890;1527085901;
1;20%;0%;2;1527085890;1527085901;
2;5%;2%;3;1527085901;1527085912;
2;20%;0%;1;1527085901;1527085912;
2;2%;0%;2;1527085901;1527085912;
3;2%;0%;5;1527085912;
3;20%;0%;1;1527085912;
3;3%;0%;2;1527085912;
[EDITED] PHP: //on the sample output I have shortened some things
$t=time();
$myfile1 = fopen("temp/time.txt", "w");
for ($i = 0; $i <= 5; $i++) {
fwrite($myfile1, $t.";\n");
}
$ranks = fopen("temp/ranks.txt", "w");
$selected_val = $_POST['rank1'].";\n".$_POST['rank2'].";\n".$_POST['rank3'].";\n".$_POST['rank4'].";\n".$_POST['rank5'].";\n".$_POST['rank6'].";";
fwrite($ranks, $selected_val);
$ranks_array = file("temp/ranks.txt",FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
$time_array = file("temp/time.txt",FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
$first_page_array = file("temp/userID.txt",FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
$second_page_array = file("data/data1.txt",FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
$final_array = [];
foreach($first_page_array as $key=>$first_page){
$final_array[] = $first_page.''.$second_page_array[$key].''.$ranks_array[$key].''.$time_array[$key]."\n";
}
file_put_contents('output.txt',$final_array, FILE_APPEND | LOCK_EX);
You can use regex to capture the different parts of the string and build it in one loop.
The regex will capture the first three items as one group then the following as one each.
Preg_match_all("/(.*?;.*?;.*?;.*?;)(.*?);(.*?)/", $str, $matches);
Foreach($matches[1] as $key => $match){
If(isset($matches[2][$key+3])){
$temp = $matches[2][$key+3] . ";";
}Else{
$temp = "";
}
$res[] = $matches[1][$key] . $matches[2][$key] . ";" . $temp;
}
Echo implode(PHP_EOL, $res);
https://3v4l.org/Nrq15
It also works if you append the file with more items later.
https://3v4l.org/s1NKS
Edit I see that you have edited your question to include more code.
This method should be used with file_get_contents and not fopen since it requires the full string in one item not as an array.
That also means it does far fewer loops than a fopen and explode method.
You haven't given us much information; however, I'll give this a go.
I assume that you have already written your text file into a string and cleaned it up (trim). We'll start from there.
1;0%;5%;4;1527085890;
1;15%;0%;1;1527085890;
1;20%;0%;2;1527085890;
2;5%;2%;3;1527085901;
2;20%;0%;1;1527085901;
2;2%;0%;2;1527085901;
3;2%;0%;5;1527085912;
3;20%;0%;1;1527085912;
3;3%;0%;2;1527085912;
First, break your working string into a working array, around your line-break character: $working = explode("\n",$workingString); (assuming a line-break called "\n")
Second, walk through the new array and break it into subarrays:
foreach($working as $values){
$subvalues = explode(";",$values);
$elements[] = $subvalues;
}
You could probably do this in a single step. I am breaking it into two for explication.
Now you should have an array that looks like this:
array $elements =
[0] => array [0] => 1
[1] => 0%
[2] => 5%
[3] => 4
[4] => 1527085890
[1] => array [0] => 1
[1] => 15%
[2] => 0%
[3] => 1
[4] => 1527085890
[2] => array [0] => 1
[1] => 20%
[2] => 0%
[3] => 2
[4] => 1527085890
[3] => array [0] => 2
[1] => 5%
[2] => 2%
[3] => 3
[4] => 1527085901
[4] => array [0] => 2
[1] => 20%
[2] => 0%
[3] => 1
[4] => 1527085901
[5] => array [0] => 2
[1] => 2%
[2] => 0%
[3] => 2
[4] => 1527085901
[6] => array [0] => 3
[1] => 2%
[2] => 0%
[3] => 5
[4] => 1527085912
Next, walk through this new array to get an array of the unique timestamps:
foreach($elements as $value){
if(!in_array($value[4],$uniqueTimestamps)){
$uniqueTimestamps[] = $value[4]
}
See where I'm going with this?
Your final walkthrough will add the second timestamp to any subarray which is missing it:
foreach($elements as $key => $value){
if(count($value) < 6){ // because you will only ever have 5 or 6 values
$k = $array_search($value,$uniqueTimestamps);
$k = $k + 1; // i.e. $k++... again, I'm writing this long-hand
// adding 1 to $k gives you the next timestamp in the unique array
$elements[$key][] = $uniqueTimestamps[$k];
}
}
To finish, walk through your $elements array and implode everything back to a $finalString, then overwrite that to your file.
I didn't test the code. Let me know if you have any troubles.
I am taking data from a CSV file and adding it to an array, in order for me to save it to my database. This is the array format:
Array
(
[0] => Array
(
[0] => Product code
[1] => Product text
[2] => Stockcode
[3] => Origin
[4] => Batchnumber
[5] => Quantity
)
[1] => Array
(
[0] => 02-018
[1] => TEMPCELL13 TIF 120 HOUR 6P/P
[2] => OK1
[3] =>
[4] =>
[5] => 13
)
[2] => Array
(
[0] => 02-038
[1] => TEMPCELL60 TIF 120 HOUR(BROWN)
[2] => OK1
[3] =>
[4] =>
[5] => 15
)
)
Where, $data[0] is the same name as my columns in my database:
So, I want to loop through all arrays, but skipping $data[0], and add this to my database. This is what I currently have:
function process_csv($file) {
$file = fopen($file, "r");
$data = array();
while (!feof($file)) {
$data[] = fgetcsv($file,null,';');
}
fclose($file);
unset($data[0]); //Unset the header information, since we only want the values to parse into our inventory database. $data[0] contains the header from the CSV = columns in our database
foreach($data as $insert){
//Insert $data to my database
// $insert[] now holds the array
}
}
What would be the best way to loop through each array and add it? Furthermore, if the "product_code" is already present in the database, it should just UPDATE that row.
You could drop the foreach statement and move your logic directly in the while loop:
$header = true;
while (!feof($file)) {
$data = fgetcsv($file,null,';');
// skip the first line
if ($header) {
$header = false;
}
else {
//Insert $data to my database
}
}
Otherwise you're looping twice (while to read the file line by line and foreach to loop the array) and consuming too much memory to build the array to loop through.
For the SQL, you can use a INSERT ... ON DUPLICATE KEY UPDATE statement: https://dev.mysql.com/doc/refman/5.7/en/insert-on-duplicate.html
When i var_dump the contents of my array, i get the following results. I would like to be able to put the following contents into a csv file. For simplicity reasons, i have not displayed all the values of the array
Array
(
[0] => Array
(
[0] => NEWS 1
[1] => 00
[2] => 0
)
[1] => Array
(
[0] => NEWS 1
[1] => 01
[2] => 0
)
[2] => Array
(
[0] => NEWS 1
[1] => 02
[2] => 0
)
[3] => Array
(
[0] => NEWS 1
[1] => 03
[2] => 0
)
[4] => Array
(
[0] => NEWS 1
[1] => 04
[2] => 0
)
)
I would like to be able to insert the contents of that array into a csv file. My final csv file should like this
NEWS 1,0,0,0,0,0
I have tried several methods without sucess. So useless to post my code here. I would like to start from scratch. If some one can advise me on the right apparoach to use or propose me some code, it will be very great
I can give you this code I wrote long time ago.. it creates a csv line from an array... maybe it can inspire you. It is in a class called CSVWriter.
private static function writeFile($handle, $data, $pos) {
if(count($data) == 0) {
return false;
} else {
$element = $pos === 0 || $pos === count($data) - 1 ? $data[$pos] : ';'.$data[$pos];
$fwrite = fwrite($handle, $element);
if($fwrite === false || ($pos + 1 === count($data))) {
return $fwrite;
} else {
CSVWriter::writeFile($handle, $data, ++$pos);
}
}
}
Can someone pls show me how to map this correctly? I am trying to understand how to use php explode() and organizing the values in a way that I can retrieve and print them in some organized matter. For each record I want to put a name=value in a particular bucket. I have (7) max buckets per record. Sometimes I have records that won't fill each bucket.
(for example record (2) is missing attributes (5,6,7) and record (3) is missing attribute (4)).
1-Column=host1.colo.sub;2-Column=Fri Aug 13;3-Column=db9.nfl.colo2.;4-Column=00:00:03;5-Column=01:55:02;6-Column=87.24 MB;7-Column=Success;
1-Column=host1.colo.sub;2-Column=Fri Aug 13;3-Column=pdb2.colo2.;4-Column=04:00:02;
1-Column=host1.colo.sub;2-Column=Fri Aug 13;3-Column=gl3_lvm;5-Column=04:48:06;6-Column=54.64 MB;7-Column=Success;
So far I wrote this to view my output:
<?php
$InputFile = file("test.txt");
foreach ($InputFile as $line){
$pieces = explode(";", $line);
//print $pieces[0];
//print $pieces[1];
//print $pieces[2];
print $pieces[3];
//print $pieces[4];
//print $pieces[5];
//print $pieces[6];
//print_r($line);
}
?>
I would like to print out similar values for each attribute instead of this where its mixed.
Using 'print $pieces[3];'
4-Column=00:00:034-Column=04:00:025-Column=04:48:06
$InputFile = file("test.txt");
foreach ($InputFile as $line){
preg_match('~(1-Column[^;]*;?)?(2-Column[^;]*)?;?(3-Column[^;]*)?;?(4-Column[^;]*)?;?(5-Column[^;]*)?;?(6-Column[^;]*)?;?(7-Column[^;]*)?;?~',$line,$pieces);
$pieces = array_pad($pieces,8,'');
echo "<pre>";print_r($pieces);echo "</pre>";
}
output:
Array
(
[0] => 1-Column=host1.colo.sub;2-Column=Fri Aug 13;3-Column=db9.nfl.colo2.;4-Column=00:00:03;5-Column=01:55:02;6-Column=87.24 MB;7-Column=Success;
[1] => 1-Column=host1.colo.sub;
[2] => 2-Column=Fri Aug 13
[3] => 3-Column=db9.nfl.colo2.
[4] => 4-Column=00:00:03
[5] => 5-Column=01:55:02
[6] => 6-Column=87.24 MB
[7] => 7-Column=Success
)
Array
(
[0] => 1-Column=host1.colo.sub;2-Column=Fri Aug 13;3-Column=pdb2.colo2.;4-Column=04:00:02;
[1] => 1-Column=host1.colo.sub;
[2] => 2-Column=Fri Aug 13
[3] => 3-Column=pdb2.colo2.
[4] => 4-Column=04:00:02
[5] =>
[6] =>
[7] =>
)
Array
(
[0] => 1-Column=host1.colo.sub;2-Column=Fri Aug 13;3-Column=gl3_lvm;5-Column=04:48:06;6-Column=54.64 MB;7-Column=Success;
[1] => 1-Column=host1.colo.sub;
[2] => 2-Column=Fri Aug 13
[3] => 3-Column=gl3_lvm
[4] =>
[5] => 5-Column=04:48:06
[6] => 6-Column=54.64 MB
[7] => 7-Column=Success
)
If your input data is so irregular you would either need to parse it with a bit more code, not just a simple explode, or prepare it so that it works as expected with explode.
In the second case, you could use strpos to find all ";" characters in the string and check if the number after them is in order. If one (or more) number was skipped you should compensate by inserting another ";". This way explode will create an empty array element and all your resulting arrays should be aligned.
While it's not exactly clear what you're trying to accomplish, hopefully this code might help you figure out what's going on.
Note that here, I've added another loop inside the main foreach, to iterate over each name/value pair in the line:
<?php
$InputFile = file("test.txt");
$lineCnt = 0;
foreach ($InputFile as $line){
$lineCnt++;
echo "Processing line #" . $lineCnt. "\n";
$pieces = explode(";", $line);
foreach($pieces as $pair){
$pair = explode('=',$pair);
if (!empty($pair[1])){
print "\t".$pair[0] .' = ' . $pair[1] . "\n";
}
}
}
The script will produce nice-looking output if run from the command-line. If you're running it in the browser, you might want to change the \n's to , and the \t's to or something.
See if this helps...
$splits = explode(';',$_POST['data']);
foreach($splits as $id => $item) {
preg_match('/(.*?)=(.*)/',$item, $matches);
$parts[$matches[1]][] = $matches[2];
}
print_r($parts);
This will give you an array with keys as 1-Column, 2-Column as so on which will contain an array of related value. You can print this array in whatever way you want.
Here is the output:
[1-Column] => Array
(
[0] => host1.colo.sub
[1] => host1.colo.sub
[2] => host1.colo.sub
)
[2-Column] => Array
(
[0] => Fri Aug 13
[1] => Fri Aug 13
[2] => Fri Aug 13
)
[3-Column] => Array
(
[0] => db9.nfl.colo2.
[1] => pdb2.colo2.
[2] => gl3_lvm
)
[4-Column] => Array
(
[0] => 00:00:03
[1] => 04:00:02
)
[5-Column] => Array
(
[0] => 01:55:02
[1] => 04:48:06
)
[6-Column] => Array
(
[0] => 87.24 MB
[1] => 54.64 MB
)
[7-Column] => Array
(
[0] => Success
[1] => Success
)