PHP search inside loaded text file, converted as array - php

I need to find a *.jpg name in a text document. For example I have a folder with pictures file1, file2 , file3 and a text document with file1, file, file3 each on a new line. I need to write near each *.jpg the text from the file, but first I need to find the corresponding row in the text document.
<?php
$arrayF = explode("\n", file_get_contents('myTxt.txt'));
// arrayF should the the array with each text line from the txt file.
while(($file = readdir($opendir)) !== FALSE)
{
if($file!="." && $file!="..")
{
$string=$file;
$arrayS = explode('.', $string);//get the name only without .jpg extension
$search=$arrayS[0];
$key = array_search($search, $arrayF);
echo $key;
}

$string=file_get_contents($file);
file_get_contents
Or if you want it line by line, just open, read and close
$fp = fopen($file, 'r');
while ($line = fread($fp)) {
//do comparision stuff
}
fclose ($fp);

Below is an example to iterate through a directory using DirectoryIterator which provides viewing contents of filesystem directories.
Example:
foreach(new DirectoryIterator($dir) as $file_info)
{
// sleep a micro bit (up to 1/8th second)
usleep(rand(0, 125000));
// disregard hidden, empty, invalid name files
if($file_info == null or $file_info->getPathname() == ''
or $file_info->isDot())
{
continue;
}
// check if its a file - log otherwise
// code omitted
// get filename and filepath
$filepath = $file_info->getPathname();
$filename = $file_info->getFilename();
// my answer to read file linked here to avoid duplication
// below "read/parse file into key value pairs"
}
read/parse file into key value pairs
To elaborate new DirectoryIterator( path to dir ) provides an iterator which can be also written as:
$iterator = new DirectoryIterator($directory);
foreach ($iterator as $fileinfo) {
// do stuffs
}
Hope this helps, indirectly.

Related

How do I delete multiple files in folder meeting a condition via PHP

I understand how to delete a specified file using the 'unlink' command in PHP, but what I need to do is to write some code that will take all (10,000+) files in a folder (possibly put them into an array), open them, and then delete ONLY files that contain specific information. (All files in the folder are .txt files containing a list, or array, of numbers. EX: I want to delete any files where 4,5,6,7th slots in the array contained 20,20,100,100 respectively).
Is this a start:
<?php
$directory = '/path/to/files';
if (! is_dir($directory)) {
exit('Invalid diretory path');
}
$files = array();
foreach (scandir($directory) as $file) {
if ('.' === $file) continue;
if ('..' === $file) continue;
$files[] = $file;
}
var_dump($files);
?>
Following on from #ShawnMehan 's and #Jigar 's comments and from my own - I have not been able to test this where I am but it might serve to point you in a direction for what you need. Not sure how many rows of arrays you have in each file, so I have used a loop but if there is only one line, you will only need the fgets().
I have assumed that your arrays in the text files are comma delimited, but if they are tab delimited you would need to explode them by "\t".
$files = array();
$each_line = array();
$file_counter = 0;
$directory = '/path/to/files';
if (! is_dir($directory)) {
exit('Invalid directory path');
}
$files = glob($directory."/*.txt"); // Scan directory for .txt files
// Check that there are .txt files in directory
if ($files !== false) {
$number_of_files = count($files); // Count number of .txt files in directory
while($file_counter < $number_of_files){
$file_handle = fopen ($files[$file_counter], "r"); // Open file
while (!feof ($file_handle)) {
// get the arrays a row at a time and put each row into array
$each_line = explode( ',', fgets($file_handle, 1000));
if($each_line[3] == 20 || $each_line[4] == 20 || $each_line [5] == 100 || $each_line[6] == 100){
unlink($file_handle);
}
}
if(file_exists($file_handle)){
fclose($file_handle);
}
$file_counter++;
}
}else{
echo "No text files found in this directory";
}
Some notes on the use of glob(); for opening files in case you may not be opening local files (it won't work on remote files): http://php.net/manual/en/function.glob.php

Search and replace entire directory file contents

I need to re-write multiple files in a single directory based on the contents of a single CSV file.
For example the CSV file would contain something like this:
define("LANG_BLABLA", "NEW");
In one of the files in the directory it would contain this:
define("LANG_BLABLA", "OLD");
The script will search through the directory and any occurrences where the CSV "LANG_BLABLA" matches the old directory LANG it will update the "OLD" with the "NEW"
My question is how exactly can I list the contents of the files in the directory in 1 array so I can easily search through them and replace where necessary.
Thanks.
Searching through a directory is relatively easy:
<?
clearstatcache();
$folder = "C:/web/website.com/some/folder";
$objects = scandir($folder, SCANDIR_SORT_NONE);
foreach ($objects as $obj) {
if ($obj === '.' || $obj === '..')
continue; // current and parent dirs
$path = "{$folder}/{$obj}";
if (strcasecmp(substr($path, -4), '.php') !== 0)
continue // Not a PHP file
if (is_link($path))
$path = realpath($path);
if ( ! is_file($path))
continue; // Not a file, probably a folder
$data = file_get_contents($path);
if ($data === false)
die('Some error occured...')
// ...
// Do your magic here
// ...
if (file_put_contents($path, $data) === false)
die('Failed to write file...');
}
As for modifying PHP files dynamically, it is probably a sign that you need to put that stuff into a database or in-memory data-store... MySQL, SQLite, MongoDB, memcached, Redis, etc. should do. Which you should use would depend on the nature of your project.
You can parse a CSV file into an array using fgetcsv http://php.net/manual/en/function.fgetcsv.php
First of all I would not recommend this workflow if you working with .php files. Try to centralize your define statements and then change it in a single location.
But here is a solution that should work for you csv files. It's not complete, you have to add some of your desired logic.
/**
* Will return an array with key value coding of your csv
* #param $defineFile Your file which contains multiple definitions e.g. define("LANG_BLABLA", "NEW");\n define("LANG_ROFL", "LOL");
* #return array
*/
public function getKeyValueArray($defineFile)
{
if (!file_exists($defineFile)) {
return array();
} else {
$fp = #fopen($defineFile, 'r');
$values = explode("\n", fread($fp, filesize($defineFile)));
$newValues = array();
foreach ($values as $val) {
preg_match("%.*\"(.*)?\",\s+\"(.*)?\".*%", $val, $matches);
$newValues[$matches[1]] = $matches[2];
}
}
}
/**
* This is s stub! You should implement the rest yourself.
*/
public function updateThings()
{
//Read your definition into an array
$defs=$this->getKeyValueArray("/some/path/to/your/file");
$scanDir="/your/desired/path/with/input/files/";
$otherFiles= scandir($scanDir);
foreach($otherFiles as $file){
if($file!="." && $file!=".."){
//read in the file definition
$oldDefinitionArray=$this->getKeyValueArray($scanDir.$file);
//Now you have your old file in an array e.g. array("LANG_BLABLA" => "OLD")
//and you already have your new file in $defs
//You now loop over both and check for each key in $defs
//if its value equals the value in the $oldDefinitionArray.
//You then update your csv or rewrite or do whatever you like.
}
}
}

Selecting file to be edited

i have an application that is used to edit .txt files. the application is made up of 3 parts
Displays contents of a folder with the files to be edited(each file is a link when clicked it opens on edit mode).
writing in to a file.
saving to file.
part 2 and 3 I have completed using fopen and fwrite functions that wasn't too hard. the part that i need help is part one currently I open the file by inputing its location and file name like so in the php file where i have the display function and save function:
$relPath = 'file_to_edit.txt';
$fileHandle = fopen($relPath, 'r') or die("Failed to open file $relPath ! ");
but what i want is for the file to open in edit mode when clicked instead of typing in the files name every time.
$directory = 'folder_name';
if ($handle = opendir($directory. '/')){
echo 'Lookong inside \''.$directory.'\'<br><br>';
while ($file = readdir($handle)) {
if($file !='.' && $file!='..'){
echo '<a href="'.$directory.'/'.$file.'">'.$file.'<a><br>';
}
}
}
this is the code that ti use to display the list of files that are in a specified folder.
Can anyone give me some pointers how I can achieve this ? any help will be greatly appreciated.
To get content of file use file_get_contents();
To put content of file use file_put_contents(); with FILE_APPEND flag for editing.
To recieve list of files in directory you can use DirectoryIterator
Example:
foreach (new DirectoryIterator('PATH/') as $fileInfo) {
if($fileInfo->isDot()) continue;
echo $fileInfo->getFilename() . "<br>\n";
}
If you don't want to put filenames you can put read files once put in db assign ids to them and use links with id param. The other solution is to store files in session array and assign keys for them. When you want to get a file you just need to provide key instead of whole filename and path.
Example with $_SESSION
$file_arr = array();
foreach (new DirectoryIterator('PATH/') as $fileInfo) {
if($fileInfo->isDot()) continue;
$file_arr[] = array("path" => $fileInfo->getPathname(), 'name' => $fileInfo->getFilename());
}
$_SESSION['files'] = $file_arr;
then in view you can use
foreach($_SESSION['files'] as $k=>$file)
{
echo "<a href='edit.php?f=".$k."'>'.$file['name'].'</a>";
}
and edit.php
$file = (int)$_GET['f'];
if(array_key_exits($file, $_SESSION['files'])
{
$fileInfo = $_SESSION[$file'];
//in file info you have now $fileInfo['path'] $fileInfo['name']
}

How to give a .php file unique name at top of page, and display unique name on index.php file

I have a question and it's probably a simple one. What I would like to do is be able to place a unique name at the top of each .php file in a folder in the php code area. I would then like a script on the index.php file to look in that folder, pull out the unique names of each .php file found at the top of each page in the php code, and display them in a list on the index.php page.
Would I have to do something like this at the top of the page:
< ?
{{{{{uniquenamehere}}}}}
? >
And If so, what would the code look like for grabbing uniquenamehere and displaying in on the index.php page?
Thanks in advance, let me know if I need to be any more clear in my question. Sorry if it's a really simple question, I'm stumped!
EDIT
Getting this warning when using answer below:
Warning: file_get_contents(test.php) [function.file-get-contents]: failed to open stream: No such file or directory in /path/index.php
Here's the code I am using,
<?php
// Scan directory for files
$dir = "path/";
$files = scandir($dir);
// Iterate through the list of files
foreach($files as $file)
{
// Determine info about the file
$parts = pathinfo($file);
// If the file extension == php
if ( $parts['extension'] === "php" )
{
// Read the contents of the file
$contents = file_get_contents($file);
// Find first occurrence of opening template tag
$from = strpos($contents, "{{{{{");
// Find first occurrence of ending template tag
$to = strpos($contents,"}}}}}");
// Pull out the unique name from between the template tags
$uniqueName = substr($contents, $from+5, $to);
// Print out the unique name
echo $uniqueName ."<br/>";
}
}
?>
Not tested, but it should be roughly something like this.
<?php
// Scan directory for files
$fileInfo = pathinfo(__FILE__);
$dir = $fileInfo['dirname'];
$files = scandir($dir);
// Iterate through the list of files
foreach($files as file)
{
// Determine info about the file
$parts = pathinfo($file);
// If the file extension == php
if ( $parts['extension'] == "php" )
{
// Read the contents of the file
$contents = file_get_contents($file);
// Find first occurrenceof opening template tag
$from = strpos($contents, "{{{{{");
// Find first occurrenceof ending template tag
$to = strpos($contents,"}}}}}");
// Pull out the unique name from between the template tags
$uniqueName = substr($contents, $from+5, $to);
// Print out the unique name
echo $uniqueName ."<br/>";
}
}

PHP, delete path from TXT file

I have, problem.. I display images from dir in ARRAY with button 'delete' - action delete.php..
If I click 'delete' file delete.php should delete image from dir and path from TXT file..
Below PHP code delete only file from dir, I don't know how I can delete PATH from TXT files - I need this script..
TXT file looking that:
../../gallery/glowna//thumb_1300625269.jpg|
../../gallery/glowna//thumb_1300625300.jpg|
../../gallery/glowna/thumb_1300626725.jpg
And delete.php
<?php
$plik=$_POST['usun'];
$nowa = substr($plik, 6, 20);
unlink('../../gallery/glowna/'.$_POST['usun']);
unlink('../../gallery/glowna/'.$nowa);
header("location:usun.php");
?>
I trying use below code, but something is wrong, because TXT file are cleaning ALL:
$txt = "../../dynamic_ajax.txt";
$img = "../../gallery/glowna/".$_POST['usun'];
$file = file_get_contents($txt, true);
$file2 = explode('|', $file);
$search=array_search($img, $file2);
unset($search);
$separator = implode("|", $file2);
file_put_contents($txt, $separator);
Ok think I understand what you mean. This is something I jotted down, you might want to clean up the code a bit.
$q = 'thumb_1300625300.jpg';
$files = file_get_contents('files.txt');
$arr = explode('|', $files);
foreach ($arr as &$file) {
if (strpos($file, $q) !== false) {
$file = '';
break;
}
}
$files = implode('|', $arr);
$files = str_ireplace('||', '|', $files);
file_put_contents('files.txt', $files);
Pretty simple code.
Opens up the file and splits it by |
Then it loops through the arrray looking for the path that matches the image and makes it empty and then skips the loop
Then you implode the string and then remove the double | because we removed an element
A couple of caveats. This script only looks for one instance of the path. If you have multiple, then let the loop run its course and remove the break. You also need to modify str_ireplace('||', '|', $files); so that it will look for multiple |
What about this?
$file = file_get_contents($txt, true);
$file2 = explode('|', $file);
$new_array = Array();
foreach ($file2 as $path) {
if (/* path should be preserved */) {
$new_array[] = $path;
}
}
$new_contents = implode("|", $new_array);
file_put_contents($txt, $new_contents);
But be aware that a little while after you put this on a public server, your TXT file will be gone. Imagine this:
1st process (thread) opens the file for writing (truncating it to 0 characters).
2nd process reads the empty file.
1st p. writes good file.
2nd process writes empty file.
You could get around that by using some lock mechanism, but consider other options. If you have only paths in that file, why not having a special folder for your images? Then just list that folder and you know which files are present. If you want to save some metadata with the images, database is your friend.

Categories