Be sure to have unique array entry - php

I have a file which contains something like :
toto;145
titi;7
tata;28
I explode this file to have an array.
I am able to display the data with that code :
foreach ($lines as $line_num => $line) {
$tab = explode(";",$line);
//erase return line
$tab[1]=preg_replace('/[\r\n]+/', "", $tab[1]);
echo $tab[0]; //toto //titi //tata
echo $tab[1]; //145 //7 //28
}
I want to be sure that data contained in each $tab[0] and $tab[1] is unique.
For example, I want a "throw new Exception" if file is like :
toto;145
titi;7
tutu;7
tata;28
or like :
toto;145
tata;7
tata;28
How can I do that ?

Convert your file to array with file(), and convert to associative array with additional duplication checking.
$lines = file('file.txt', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
$tab = array();
foreach ($lines as $line) {
list($key, $val) = explode(';', $line);
if (array_key_exists($key, $tab) || in_array($val, $tab)) {
// throw exception
} else {
$tab[$key] = $val;
}
}

Store them as key => value pairs in an array, and check whether each key or value already exists in your array as you are looping through the file. You can check for an existing key with array_key_exists and an existing value with in_array.

One simple is using array_unique, save the parts (tab[0] and tab[1]) into two separate arrays after you explode, name them for example $col1 and $col2 and then, you could do this simple test:
<?php
if (count(array_unique($col1)) != count($col1))
echo "arrays are different; not unique";
?>
PHP will turn your array parts into unique, if duplicated entrys exist, so if the size of the new array differs from the original, it means that it was not unique.

//contrived file contents
$file_contents = "
toto;145
titi;7
tutu;7
tata;28";
//split into lines and set up some left/right value trackers
$lines = preg_split('/\n/', trim($file_contents));
$left = $right = array();
//split each line into two parts and log left and right part
foreach($lines as $line) {
$splitter = explode(';', preg_replace('/\r\n/', '', $line));
array_push($left, $splitter[0]);
array_push($right, $splitter[1]);
}
//sanitise left and right parts into just unique entries
$left = array_unique($left);
$right = array_unique($right);
//if we end up with fewer left or right entries than the number of lines, error...
if (count($left) < count($lines) || count($right) < count($lines))
die('error');

Use associative arrays with keys "toto", "tata" etc.
To check whether a key exists you can use array_key_exists or isset.
BTW. Instead of preg_replace('/[\r\n]+/', "", $tab[1]), try trim (or even rtrim).

While you're traversing the array add the values to an existing array, i.e. placeholder, which will be used to check if the value exists or not via in_array().
<?php
$lines = 'toto;145 titi;7 tutu;7 tata;28';
$results = array();
foreach ($lines as $line_num => $line) {
$tab = explode(";",$line);
//erase return line
$tab[1]=preg_replace('/[\r\n]+/', "", $tab[1]);
if(!in_array($tab[0]) && !in_array($tab[1])){
array_push($results, $tab[0], $tab[1]);
}else{
echo "value exists!";
die(); // Remove/modify for different exception handling
}
}
?>

Related

PHP iterate through each row of csv and return row with matching element

I have a csv file called data.csv.
Here's a sample of what's in data.csv
Microsoft,2020-02-13,"Sample",tt,aa,qq,w,ee,rr,tt,", ",", ",", ","2020-02-13 16:03:08"
Google,2020-02-13,"HQ",tt,aa,qq,w,ee,rr,tt,", ",", ",", ","2020-02-13 16:10:48"
I'm trying to iterate through each row of the csv and check if user inputted variable (lets say var="Microsoft") matches the first value in any row. If it does match, then return all the elements in that row as an array. (tried this using fgetcsv but returns whole csv file)
Here's what I have tried so far:
foreach ($csv as $line) {
if ($line[0] == 'Microsoft') {
$file = fopen("data.csv","r");
echo(fgetcsv($file));
fclose($file);
}
}
$csv = array_map('str_getcsv', file('./temp.csv'));
foreach ($csv as $line) {
if ($line[0] == 'Microsoft') {
echo implode(', ',$line);
}
}
If the first column's value is suitable as an array index. You can use array_column to re-index by your first column:
<?php
$result = array_column(array_map('str_getcsv', file('data.csv')), null, 0)['Microsoft'] ?? null;

Insert multiple arrays

I'm trying to grab all values from my inputs and insert them together, so for each value #1 in first array, insert value #1 in second and third. This is kind of what it looks like:
$lines = explode(PHP_EOL, $_POST['links']);
$keywords = explode(PHP_EOL, $_POST['keywords']);
$violationtypes = explode(PHP_EOL, $_POST['keywords']);
Those inputs are regular, but they may be 1 or 500, I honestly don't know. I used to handle this while there was one input like this:
foreach($lines as $line)
{
if (!empty($line))
{
if (false === strpos($line, '://'))
{
$line = 'http://' . $line;
}
mysql_query("INSERT INTO links (ClientEmail,Links) VALUES ('$Emailvalue', '$line')");
}
}
However, I can't pull this one with 3 arrays. Is there a better way?
PS The check for empty lines is so that I don't add empty values into the database, and the other one is checking if http:// is there, and adds it if its not. That check is only for $lines, other inputs don't need any check
Use the index in one array to fetch the corresponding elements of the other arrays:
foreach ($lines as $i => $line) {
if (!empty($line)) {
$keyword = $keywords[$i];
$violation = $violationtypes[$i];
// Now insert $line, $keyword, and $violation into DB
}
}

How can I echo specific line from a text area using php

I am collecting html text area data to echo in php.I am able to select all data using
$devices = explode("\n", $_POST['devs']);
foreach($devices as $device)
echo $device;
and I am able to select only the first line using:
$first_line = strstr(($_POST['devs']), "\n", true);
echo $first_line;
But How can I echo specific lines ? say line 2 or 4 from text area ?
Usage:
getLines(YOUR POST, START LINE, END LINE(optional));
With return array:
function getLines($text, $start, $end = false)
{
$devices = explode("\n", $text);
$append = "My device is ";
$output = array();
foreach ($devices as $key => $line)
{
if ($key+1 < $start) continue;
if ($end && $key+1 > $end) break;
$output[] = $append.$line;
}
return $output;
}
$array = getLines($_POST['devs'], 2);
var_dump($array);
With echo string:
function getLines($text, $start, $end = false)
{
$devices = explode("\n", $text);
$append = "My device is ";
$output = "";
foreach ($devices as $key => $line)
{
if ($key+1 < $start) continue;
if ($end && $key+1 > $end) break;
$output .= $append.$line."<br />";
}
return $output;
}
echo getLines($_POST['devs'], 2);
Your first code snippet is already creating an array of lines via the explode function.
As such, to output the 2nd and 4th lines, you can simply use:
$devices = explode("\n", $_POST['devs']);
echo $devices[1];
echo $devices[3];
If you're new to PHP (I'm guessing this is the case due to the nature of your question), it should be noted that like many programming languages, arrays are indexed from zero, hence line 2 is 1, line 4 is [3], etc.
UPDATE
To access the penultimate (i.e.: 2nd to last) line, you could use:
echo $devices[count($devices) - 2];
What we're doing here is getting the number of elements in the array (via count) and then subtracting two to fetch the second last element. (As we need to subtract one to deal with the fact that arrays are indexed from zero.)
Do it like this
$nth_line = explode("\n", $_POST['devs'])[n];
where n is you line no.
the explode() returns an array then you can select each element by basic array operation
further readings http://php.net/manual/en/function.explode.php
because $devices is an array after exploding it, you can treat each line by it's index. Reminder that arrays are zero-index based so 1 starts at 0.
$devices = explode('\n', $_POST['devs']);
// line 1
echo $devices[0];
// line 2
echo $devices[1];
// line 4
echo $devices[3];
you can use split:
$lines = split("\n", $_POST['devs']);
echo $lines[3]; //4th line
See documentation http://php.net/manual/es/function.split.php
Take a look at array operations in PHP. Since $devices is an array you can select an element by its index like this: $devices[1] for second element, $devices[2] for third etc.
Lookup your syntax on php.net. It is
$devices = explode(";", "aap;noot;mies");
print_r($devices);
foreach ($devices as $key => $value) {
echo "<br>nr.$key=" . $devices[$key];
}

Parsing a formatted text file in PHP

Is there an easy way to parse the following data that I will post below. The data comes from the web.
I was using the $rows = explode("\n", $txt_file); then the $parts = explode('=', $line_of_text); to get the key name and values. However, I don't know how to handle the extra information that I do not want.
Additionally, I do not know how to get rid of the extra spaces. The file seems to be made for some kind of easy parsing. I have looked all over this site to find a solution. However, this data is quite different than the examples I have found on this site.
# This file holds all the timelines available at this time.
# All lines starting with # is ignored by parser...
#
STARTINFO
description = Rubi-Ka 2
displayname = Rimor (Rubi-Ka 2)
connect = cm.d2.funcom.com
ports = 7502
url =
version = 18.5.4
ENDINFO
STARTINFO
description = Rubi-Ka 1
displayname = Atlantean (Rubi-Ka 1)
connect = cm.d1.funcom.com
ports = 7501
url =
version = 18.5.4
ENDINFO
You can use the trim function to get rid of the whitespace.
To only keep the columns you want, you can store their keys in an array, and make a check against it when parsing.
Here's an example (albeit rather verbose).
<?
$lines = explode("\n", $data);
$result = array();
$count = 0;
// an array of the keys we want to keep
// I have the columns as keys rather then values for faster lookup
$cols_to_keep = array( 'url'=>null, 'description'=>null, 'ports'=>null, 'displayname' => null);
foreach($lines as $line)
{
//skip comments and empty lines
if(empty($line) || $line[0] == '#')
{ continue; }
//if we start a new block, initalize result array for it
if(trim($line) == 'STARTINFO')
{
$result[$count] = array();
continue;
}
// if we reach ENDINFO increment count
if(trim($line) == 'ENDINFO')
{
$count++;
continue;
}
//here we can split into key - value
$parts = explode('=', $line);
//and if it's in our cols_to_keep, we add it on
if(array_key_exists(trim($parts[0]), $cols_to_keep))
{ $result[$count][ trim($parts[0]) ] = trim( $parts[1] ); }
}
print_r($result);
?>

How can I read a text file with 200 lines of text, and identify identical string values?

I have a text file that contains 200 lines of text. How can I compare each line of text and identify the same values with PHP. Is that even possible?
Can I convert the lines to XML format?
Can I convert the text file to HTML and append the duplicate values to an un-ordered list?
Are you looking to make an array of duplicate lines? If so, you could use something like this:
<?php
/* load the file as an array of lines */
$lines = file('myfile');
/* put them in sorted order */
sort($lines);
/* loop over each line comparing it to the previous, to determine if it is a dup */
$last_line = null;
$duplicates = array();
foreach ($lines as $line)
{
/* only add it to the duplicates array if it is not already there */
if (strcmp($line, $last_line) == 0 && ! in_array($line, $duplicates))
{
$duplicates[] = $line;
}
$last_line = $line;
}
/* view the duplicates */
var_dump($duplicates);
?>
I'll answer you one question, first: Yes, you can. I'm tired so I'll sholl you just messy and unusable code in production case
$lines = file("file.txt");
sort($lines);
foreach ($lines as $line)
{
if (in_array($line, $lines) && !in_array($line, $dupes))
{
$dupes[] = $line;
}
}
print_r($dupes);

Categories