PHP - Searching words in a .txt file - php

I have just learnt some basic skill for html and php and I hope someone could help me .
I had created a html file(a.html) with a form which allow students to input their name, student id, class, and class number .
Then, I created a php file(a.php) to saved the information from a.html into the info.txt file in the following format:
name1,id1,classA,1
name2,id2,classB,24
name3,id3,classA,15
and so on (The above part have been completed with no problem) .
After that I have created another html file(b.html), which require user to enter their name and id in the form.
For example, if the user input name2 and id2 in the form, then the php file(b.php) will print the result:
Class: classB
Class Number: 24
I have no idea on how to match both name and id at the same time in the txt file and return the result in b.php

example data:
name1,id1,classA,1
name2,id2,classB,24
name3,id3,classA,15
<?php
$name2 = $_POST['name2'];
$id2 = $_POST['id2'];
$data = file_get_contents('info.txt');
if($name2!='')
$konum = strpos($data, $name2);
elseif($id2!='')
$konum = strpos($data, $id2);
if($konum!==false){
$end = strpos($data, "\n", $konum);
$start = strrpos($data, "\n", (0-$end));
$row_string = substr($data, $start, ($end - $start));
$row = explode(",",$row_string);
echo 'Class : '.$row[2].'<br />';
echo 'Number : '.$row[3].'<br />';
}
?>

Iterate through lines until you find your match. Example:
<?php
$csv=<<<CSV
John,1,A
Jane,2,B
Joe,3,C
CSV;
$data = array_map('str_getcsv', explode("\n", $csv));
$get_name = function($number, $letter) use ($data) {
foreach($data as $row)
if($row[1] == $number && $row[2] == $letter)
return $row[0];
};
echo $get_name('3', 'C');
Output:
Joe

You could use some simple regex. For example:
<?php
$search_name = (isset($_POST['name'])) ? $_POST['name'] : exit('Name input required.');
$search_id = (isset($_POST['id'])) ? $_POST['id'] : exit('ID input required.');
// First we load the data of info.txt
$data = file_get_contents('info.txt');
// Then we create a array of lines
$lines = preg_split('#\\n#', $data);
// Now we can loop the lines
foreach($lines as $line){
// Now we split the line into parts using the , seperator
$line_parts = preg_split('#\,#', $line);
// $line_parts[0] contains the name, $line_parts[1] contains the id
if($line_parts[0] == $search_name && $line_parts[1] == $search_id){
echo 'Class: '.$line_parts[2].'<br>';
echo 'Class Number: '.$line_parts[3];
// No need to execute the script any further.
break;
}
}

You can run this. I think it is what you need. Also if you use post you can change get to post.
<?php
$name = $_GET['name'];
$id = $_GET['id'];
$students = fopen('info.txt', 'r');
echo "<pre>";
// read each line of the file one by one
while( $student = fgets($students) ) {
// split the file and create an array using the ',' delimiter
$student_attrs = explode(',',$student);
// first element of the array is the user name and second the id
if($student_attrs[0]==$name && $student_attrs[1]==$id){
$result = $student_attrs;
// stop the loop when it is found
break;
}
}
fclose($students);
echo "Class: ".$result[2]."\n";
echo "Class Number: ".$result[3]."\n";
echo "</pre>";

strpos can help you find a match in your file. This script assumes you used line feed characters to separate the lines in your text file, and that each name/id pairing is unique in the file.
if ($_POST) {
$str = $_POST["name"] . "," . $_POST["id"];
$file = file_get_contents("info.txt");
$data = explode("\n", $file);
$result = array();
$length = count($data);
$i = 0;
do {
$match = strpos($data[$i], $str, 0);
if ($match === 0) {
$result = explode(",", $data[$i]);
}
} while (!$result && (++$i < $length));
if ($result) {
print "Class: " . $result[2] . "<br />" . "Class Number: " . $result[3];
} else {
print "Not found";
}
}

Related

How can i add a number to a file name in php

Goodevening to everyone, how can i add a number to a file name in php.
Let me explain; I want to save a file using a dropzone but i want to rename the file if it exist in the folder.
I've written down this code but the regex doesn't work and also if it's possible to insert the number before the extension of the file like google chrome does.
if(file_exists($target_file)){
if(preg_match_all($target_file, "'('[0-9]{1,}')'")==false){
$target_file= $target_path."(1)".$name;
}else{
$pos=preg_match_all($target_file, "'('[0-9]{1,}')'");
$pos=$pos++;
$pos1=strpos($pos, $target_file, ")");
$pos1=$pos1-$pos;
$num=substr($target_file, $pos, $pos1);
$num = (int)$num;
$num =$num++;
$sostituisci="(".$num.")";
$target_file=preg_replace("'('[0-9]{1,}')'", $sostituisci, $target_file);
}
}
$name is the name of the file i want to save with the extension
the first $target_file of the code contain the full path + the name of the file
$target_file is a sting like /dropzone/upload/filename.txt and $name is a string like filename.txt. If the $targetfile exist i would to rename the $name like filename(1).txt or filename(2).txt and so on
also other solutions are accepted like a js library.
I assume you are referring to this set of code here.
if(preg_match_all($target_file, "'('[0-9]{1,}')'")==false){
$target_file= $target_path."(1)".$name;
}
insert the number before the extension of the file
EDIT: Use explode() and re-format the ext.
EXAMPLE:
$target_path = "/assets/imgages/";
$name = 'img.jpg';
$name = explode('.', $name);
$format = $name[0].'(1).'.$name[1];
$path = $target_path.$format;
Will produce the following string:
/assets/img/notes(1).txt
Accept multiple dots in string.
$filename = 'company.jobtitle.field.text';
function formatDuplicateExtension($filename){
$stmt = NULL;
$format = explode('.', $filename);
$i = 0;
foreach($format as $key => $value){
if($value === end($format)){
$stmt .= '(1).'.$format[$i];
}elseif($key === count($format)-2){
$stmt .= $format[$i];
}else{
$stmt .= $format[$i].'.';
}
$i++;
}
return $stmt;
}
echo formatDuplicateExtension($filename);
$filename = 'company.jobtitle.field.text';
OUTPUTS: //-->/assets/imgages/company.jobtitle.field(1).text
$name = 'trees.vac2012.img.jpg';
OUTPUTS: //--> /assets/imgages/trees.vac2012.img(1).jpg
I've found a solution idk if it's the best one because regex searches and substitutions are involved a lot of times and it seems to be they're resources consuming functions.
//this function insert the $number in the name of the file before .extension
function InsertBeforeExtension($filename,$number){
$stmt = NULL;
$format = explode('.', $filename);
$i = 0;
foreach($format as $key => $value){
if($value === end($format)){
$stmt .= '('.$number.').'.$format[$i];
}elseif($key === count($format)-2){
$stmt .= $format[$i];
}else{
$stmt .= $format[$i].'.';
}
$i++;
}
return $stmt;
}
//this function check if there's a string like (number).ext in the name
//if yes increment the (number) in the string that become (number++).ext
//if no insert (1) before .ext
function insertnumber($string){
$matches=array();
$re = '/[(][0-9]+[)]\.[a-zA-Z]+/m';
preg_match_all($re, $string, $matches, PREG_SET_ORDER, 0);
if($matches[0][0]){
//if (number).ext is present
$re = '/[(][0-9]+[)]/m';
$str = $matches[0][0];
//select the (number) only
preg_match_all($re, $str, $matches, PREG_SET_ORDER, 0);
//remove parethesis
$str=substr($matches[0][0],1,-1);
//cast sting to an int for add a number
$int = (int)$str;
$int++;
//replace the last (number) match in the name of the file with (number++)
$re = '/(.*)[(][0-9]+[)]/m';
$subst = '${1}('.$int.')';
$result = preg_replace($re, $subst, $string);
}else{
//if (number).ext is not present insert (1) before .ext
$result=InsertBeforeExtension($string,1);
}
return $result;
};
$target_file = $target_path.$name;
//If the file exist repeat to find the number of file that doesn't exist
if( file_exists( $target_file )) {
while(file_exists( $target_file )){
$name=insertnumber($name);
$target_file = $target_path.$name;
}
}
The only problem is that if you have uploaded a file named like file(3).txt and you upload another file with the same name this function rename it in file(4).txt and not in file(3)(1).txt but for my scope this is not important
I've commented the code trying to be the most clear possible this solution seems to work well but i've not calculate the performance.

Removing some strings in a word in PHP within an array

I am have retrieved all the file contents from a directory. It prints the file contents name from an array. However I want only a portion of the file content name. Any idea how can I achieve this? I have tried using the following:
The file contents from the directory has format: pdb101m.ent.gz , pdb102l.ent.gz
I want to retrieve only the 101m and 102l
<?php
$dir = "C:/Users/Desktop/EAD/PDB/";
$files = array();
$dh = opendir($dir);
while (false !== ($filename = readdir($dh))) {
$files[] = $filename;
}
foreach($files as $ex){
echo str_replace('pdb.ent.gz', ' ', $ex). '<br>';
}
?>
Please help. Grateful.
Use substr() function:
echo substr('pdb101m.ent.gz',3,4); // Outputs: 101m
echo substr('pdb102l.ent.gz',3,4); // Outputs: 102l
So:
foreach($files as $ex){
echo substr($ex, 3,4). '<br>';
}
Edit: Update my answer attending the OP new request:
So in your query you should use:
foreach ($files as $ex) {
$search = substr($ex, 3, 4);
$sql = 'SELECT DISTINCT `pdb_code` FROM pdb WHERE `pdb_code` <> "' . $search . '" LIMIT 6';
$result = mysql_query($sql) or die(mysql_error());
while ($row = mysql_fetch_array($result)) {
$pdb[] = $row['pdb_code'];
}
}
If it's always pdb at the beggining and .ent.gz at the end you can do simply:
echo substr('pdb101m.ent.gz',3,-7);
Negative value of third parameter in substr() means
that many characters will be omitted from the end of string

Creating a page that detects multiple usernames when they login.PHP

I want to increment $userCount by 1 every time $data and $fileLineArr2[0] have the same value. Could someone explain why $userCount remains 0? I'm a programming student, so please keep help in a way that is understandable to someone with only intermediate experience.
if(!empty($_GET["user"]) && !empty($_GET["pass"]) && !empty($_GET["fname"]) && !empty($_GET["lname"])){
$handle = fopen($accountInfo, 'a') or die('Cannot open file: '.$accountInfo);
$data = $_GET["user"]."; ";
$data = strtoupper($data);
fwrite($handle, $data);
$data2 = $_GET["pass"]."; ";
fwrite($handle, $data2);
$data3 = $_GET["fname"]."; ";
fwrite($handle, $data3);
$data4 = $_GET["lname"].";\n";
fwrite($handle, $data4);
fclose($handle);
$reading2 = fopen($accountInfo, 'r') or die('Cannot open file: '.$accountInfo);
echo "$userCount";
while(!feof($reading2)){
$fileLines2 = fgets($reading2);
$fileLineArr2 = (explode("; ", $fileLines2));
//print_r($fileLineArr2);
**if($fileLineArr2[0] == $data)
{
$userCount++;
}**
echo "$fileLineArr2[0] ";
echo " $data". "\n";
echo "$userCount";
}
fclose($reading2);
if($userCount > 1)
{
$validSignUp = false;
?>
<font color='red'>Username already taken!</font>
<?php
}
elseif($userCount == 0)
{
;
}
else
{
$validLogin = true;
$validSignUp = true;
}
}
When reading from a file, there is an invisible new line character at the end of the string. You will want to remove that and then compare against the $data.
To remove the new line character, you can do something like
$string = trim(preg_replace('/\s+/', ' ', $string));
Where $string is the line from the file.
EDIT
Based on a discussion in the comments section, this is not what you want.
What you will want to do is the following:
$line = explode('; ', $lineData);
Where $lineData is the information being read from the file.
This will give you an array of all the elements that were listed on the line. We know that the username is listed in the first position, IE $line[0]. So we compare our data with that.
if ($line[0] == $data) {
$userCount++;
}
Where $data is the information we are comparing against.

Read file and store into a variable

<?php
$userName = array();
$tutorial = array();
$myFile = "students.txt";
$fh = fopen($myFile,'r');
while( !feof($myFile) ){
$userName[] = array(fgets($fh));//Save first line content
$tutorial[] = array(fgets($fh));//Save second line content
}
fclose($myFile);
echo "$userName";
echo "$tutorial";
?>
and my students.txt content
dasdsa
A
asdasd
D
How to read that and store into different array and print them out
your code should work as expected. I assume you're bit confused with echo "$userName"; output as it displays Array word. try var_dump($userName) instead
Do exactly as you've done, but change
$userName[] = array(fgets($fh));//Save first line content
$tutorial[] = array(fgets($fh));//Save second line content
to
$userName[] = fgets($fh);//Save first line content
$tutorial[] = fgets($fh);//Save second line content
(no need to keep the subitems in their own seperate array)
and print them out by either using print_r, or iterate through them:
for ($i = 0; $i < count($userName); $i++) {
echo $userName[$i] . " - " . $tutorial[$i];
}
$text = file_get_contents('students.txt');
$text = explode("\n",$text);
$output = array();
foreach($text as $line)
{
$output[] = $line;
}
Use function file() in PHP
file — Reads entire file into an array
$array_lines = file('students.txt');
$count = count($array_lines);
$first_arr = array();
$sec_arr = array();
foreach ($array_lines as $i => $line){
if($i%2) $first_arr[] = $line;
else $sec_arr[] = $line;
}
print_r($first_arr);
print_r($sec_arr);
With file() function every line is read as element in array. You can check it with:
print_r($first_arr);

Return in array

I have these php lines:
<?php
$start_text = '<username="';
$end_text = '" userid=';
$source = file_get_contents('http://mysites/users.xml');
$start_pos = strpos($source, $start_text) + strlen($start_text);
$end_pos = strpos($source, $end_text) - $start_pos;
$found_text = substr($source, $start_pos, $end_pos);
echo $found_text;
?>
I want to see just the names from entire file, but it shows me just the first name. I want to see all names.
I think it is something like: foreach ($found_text as $username).... but here I am stuck.
Update from OP post, below:
<?php
$xml = simplexml_load_file("users.xml");
foreach ($xml->children() as $child)
{
foreach($child->attributes() as $a => $b)
{
echo $a,'="',$b,"\"</br>";
}
foreach ($child->children() as $child2)
{
foreach($child2->attributes() as $c => $d)
{
echo "<font color='red'>".$c,'="',$d,"\"</font></br>";
}
}
}
?>
with this code, i receive all details about my users, but from all these details i want to see just 2 or 3
Now i see :
name="xxx"
type="default"
can_accept="true"
can_cancel="false"
image="avatars/trophy.png"
title="starter"
........etc
Another details from the same user "Red color(defined on script)"
reward_value="200"
reward_qty="1"
expiration_date="12/07/2012"
.....etc
what i want to see?
i.e first line from first column "name="xxx" & expiration_date="12/07/2012" from second column
You will need to repeat the loop, using the 3rd parameter, offset, of the strpos function. That way, you can look for a new name each time.
Something like this (untested)
<?php
$start_text = '<username="';
$end_text = '" userid=';
$source = file_get_contents('http://mysites/users.xml');
$offset = 0;
while (false !== ($start_pos = strpos($source, $start_text, $offset)))
{
$start_pos += strlen($start_text);
$end_pos = strpos($source, $end_text, $offset);
$offset = $end_pos;
$text_length = $end_pos - $start_pos;
$found_text = substr($source, $start_pos, $text_length);
echo $found_text;
}
?>
You should either use XMLReader or DOM or SimpleXML to read XML files. If you don't see the necessity, try the following regular expressions approach to retrieve all usernames:
<?php
$xml = '<xml><username="hello" userid="123" /> <something /> <username="foobar" userid="333" /></xml>';
if (preg_match_all('#<username="(?<name>[^"]+)"#', $xml, $matches, PREG_PATTERN_ORDER)) {
var_dump($matches['name']);
} else {
echo 'no <username="" found';
}

Categories