I'm writing a news script, and I'm having trouble making a way for the files to be deleted.
How can I change this script so that the <input type="checkbox" /> has a value of the file in the same row?
<?php
// This function reads all available news
function getNewsList(){
$fileList = array();
// Open the actual directory
if ($handle = opendir("news")) {
// Read all file from the actual directory
while ($file = readdir($handle)) {
if (!is_dir($file)) {
$fileList[] = $file;
}
}
}
rsort($fileList);
return $fileList;
}
// new
$list = getNewsList();
print("<table>\n");
print("<tr><td> </td><td>Article Title:</td><td>Post Date:</td></tr>\n");
foreach ($list as $value) {
$newsData = file("news/".$value);
$newsTitle = $newsData[0];
$submitDate = $newsData[1];
unset ($newsData['0']);
unset ($newsData['1']);
$newsContent = "";
foreach ($newsData as $value) {
$newsContent .= $value;
}
print("<tr>");
print("<td><input type=\"checkbox\" name=\"check_files[]\" value=\"$file\" /></td>");
print("<td>$newsTitle</td>");
print("<td>");
print("$submitDate");
print("</td>");
print("</tr>\n");
}
print("</table>\n");
I have a similar script for managing files, and it's something like $dirArray[$index] for the file name, but I can't figure out how to adapt this script to work the same way, because I'm too new to PHP.
Thanks for the help!
EDIT: This is the line where the file name needs to be: (instead of $file, which doesn't work for some reason):
print("<td><input type=\"checkbox\" name=\"check_files[]\" value=\"$file\" /></td>");
The $file variable isn't defined anywhere, you could try this:
replace
$newsData = file("news/".$value);
with
$file="news/".$value;
$newsData = file($file);
In your script, it looks like the current file name is stored in $value, because $list = getNewsList(); is an array of filenames, and your doing a foreach on it : foreach ($list as $value) {
Try replacing the second foreach loop with:
foreach ($newsData as $content) {
$newsContent .= $content;
}
and then use this line to show the file:
print("<td><input type=\"checkbox\" name=\"check_files[]\" value=\"$value\" /></td>");
Related
I am trying to pass an array value into a function, but can't seem to get it to work. Here is what I am trying to do
I have a folder on my server called /Rpt
The /Rpt folder has a bunch of different folders inside of it (30 of them) - these folders contain a bunch of different files in them
I want to check most of the folders in /Rpt, and get the name and date of the latest file (based on last modified or created date) ... i want to store the results into an array, that has (folder path, file name of last file, file date of last file)
This query gets the folders that need to be checked
$sql = "my SQL here";
$stmt = $dbh->prepare($sql);
$stmt->execute();
$arrValues = $stmt->fetchAll(PDO::FETCH_ASSOC);
This is a function that checks the specified folder, and displays the info i need (folder path, file name, file date)
function GetFileNameDate($location, $file_name, $file_date) {
$files = scandir($location);
$path = $location;
foreach ($files as $file) {
if (strpos($file, " ") !== false) {
$filename = $file;
$last_updated = date ("F d Y H:i:s", filemtime($path.'\\'.$file));
$results = array($filename=>$last_updated);
$file_name = key($results);
$file_date = reset($results);
return array($location, $file_name, $file_date);
}
}
}
When i call the function - and enter a specific path link in this example, it works OK and i shows the values i want to see
$FileNameDate = GetFileNameDate('E:\Rpt\FolderA');
echo $FileNameDate[0];
echo $FileNameDate[1];
echo $FileNameDate[2];
echo "<br/><br/>";
This is where I am having problems
I am trying to pass an array (list of folders from my SQL query) into the function, so i can output the (folder path, name of latest file, date of latest file) for each of the folders from SQL query
When i echo $locations (it lists all the folders which i am trying to pass to the function)
foreach ($arrValues as $row){
$locations = array($row['Folder']);
$FileNameDate = GetFileNameDate($locations);
echo $FileNameDate[0];
echo $FileNameDate[1];
echo $FileNameDate[2];
}
As per suggestion from #lovelace I also tried the following, but again just a blank page.
foreach ($arrValues as $row){
$locations = array($row['Folder']);
foreach ($locations as $FolderPath) {
$FileNameDate = GetFileNameDate($FolderPath);
echo $FileNameDate[0];
echo $FileNameDate[1];
echo $FileNameDate[2];
}
}
SOLUTION
see comment below to how above was fixed ... however I ended up implementing what i wanted a different way, sharing it in case anyone else needs similar functionality
function GetFileNameDate($location) {
$files = scandir($location);
$path = $location;
foreach ($files as $file) {
$iterator = new DirectoryIterator($path);
$mtime = 0;
$file = "";
foreach ($iterator as $fileinfo) {
if ($fileinfo->isFile()) {
if ($fileinfo->getMTime() > $mtime) {
$file = $fileinfo->getFilename();
$mtime = $fileinfo->getMTime();
}
}
}
return array($path, $file, $mtime);
}
}
foreach ($arrValues as $row){
$locations = array(rtrim($row['Folder']));
foreach ($locations as $FolderPath) {
$FileNameDate = GetFileNameDate($FolderPath);
echo $FileNameDate[0]; #folder
echo $FileNameDate[1]; #file
echo $FileNameDate[2]; #date
}
}
I have a script which takes a zipped CSV file, unzips it, and removes duplicate entries. It was mostly working, until I moved the unzip code into a function. Now it fails to unzip the .zip file, but doesn't show an error.
Checked file/folder permissions, everything is 777 on dev machine.
<?php
//
//huge memory limit for large files
$old = ini_set('memory_limit', '8192M');
//
//create a string like the filename
$base_filename = 'csv-zip-file'.date('m').'_'.date('d').'_'.date('Y');
//
//if the file exists ...
//unzip it
//read it to an array
//remove duplicates
//save it as a new csv
if (file_exists($base_filename.'.zip')) {
$zip_filename = $base_filename.'.zip';
echo "The file <strong>$zip_filename</strong> exists<br>";
unzip($zip_filename);
$csv = csv_to_array();
$csv = unique_multidim_array($csv,"Project Id");
var_dump($csv);
} else {
echo "The file <strong>$base_filename.zip</strong> does not exist";
}
function unzip($file_to_unzip) {
$zip=new ZipArchive();
if($zip->open($file_to_unzip)==TRUE) {
$address=__DIR__;
$zip->extractTo($address);
$res=$zip->close();
echo 'ok';
}
else{
echo 'failed';
}
}
function unique_multidim_array($array, $key) {
$temp_array = array();
$i = 0;
$key_array = array();
foreach($array as $val) {
if (!in_array($val[$key], $key_array)) {
$key_array[$i] = $val[$key];
$temp_array[$i] = $val;
}
$i++;
}
return $temp_array;
}
function csv_to_array () {
// global $filename;
global $base_filename;
$rows = array_map('str_getcsv', file($base_filename.'.csv'));
//using array_pop to remove the copyright on final row
array_pop($rows);
$header = array_shift($rows);
$csv = array();
foreach ($rows as $row) {
$csv[] = array_combine($header, $row);
}
return $csv;
}
Interesting problem you have here.
Output $file_to_unzip right inside the function.
Does $zip->* have an last_error or last_response method? See
what the ZipArchive class IS returning.
Do you have access to the php error logs? Let's look there for any output.
For a simple voting system, i put the values into a .txt file.
This is the array i use:
$quickpolloptions = ['Mozilla', 'Chrome', 'Opera', 'IE', 'Safari'];
This is the form:
<form method="post" id="quickpoll">
foreach ($quickpolloptions as $key => $value) {
echo "<tr>";
echo "<td>";
echo "<label>$value</label>";
echo "</td>";
echo "<td>";
echo "<input type='checkbox' name='checkboxvote[]' value='$key'><br>";
echo "</td>";
echo "</tr>";
}
<input type="submit" value="Submit">
</form>
This is how i store the data:
$result_file = "data/vote_result.txt";
if (file_exists($result_file)) {
$results = explode(',', file_get_contents('data/vote_result.txt'));
} else {
// start with zeros if you don't have a file yet
$results = array_fill(0, count($quickpolloptions), 0);
}
// below i am trying to read each value fromn checkbox and store in .txt file
if (isset($_POST['checkboxvote'])) {
foreach ($_POST['checkboxvote'] as $checkbox) {
$results[$_POST['checkboxvote']]++;
file_put_contents('data/vote_result.txt', implode(',', $results));
}
}
So i do not succeed in the last part: to put multiple values in the txt file.
How can i do that?
Use the $checkbox variable as the key to $results when incrementing the values. Also, don't write to the file inside the loop. Just update the array and then write to the file once.
if (isset($_POST['checkboxvote'])) {
foreach ($_POST['checkboxvote'] as $checkbox) {
$results[$checkbox]++;
}
file_put_contents('data/vote_result.txt', implode(',', $results));
}
In your foreach loop you are looping over $_POST['checkboxvote'] which is correct. However $checkbox is the element.
Second, you are inserting the value into the index of $results, you need them as the data of the results so implode will combine them.
Lastly, you should call file_put_contents() outside of your foreach loop. If you call it multiple times it will appear to work correctly but it will be wasting time by overwriting your file each loop.
foreach ($_POST['checkboxvote'] as $checkbox) {
$results[] = $checkbox;
file_put_contents('data/vote_result.txt', implode(',', $results));
}
or
foreach ($_POST['checkboxvote'] as $key => $checkbox) {
$results[] = $_POST['checkboxvote'][$key];
file_put_contents('data/vote_result.txt', implode(',', $results));
}
I think $results[$_POST['checkboxvote']]++; should be $results[$checkbox]++;
Note that your implementation is susceptible to race conditions if two people vote at the same time.
You should use file locks or consider an RDBMS with transaction protection.
Example:
if (isset($_POST['checkboxvote'])) {
/* lock the file to prevent a race condition */
$file_handle = fopen($result_file, 'a+');
$locked = flock($file_handle, LOCK_EX);
/* retrieve the results now that we are locked */
$results = fgets($file_handle);
if ($results !== false) {
$results = explode(',', $results);
} else {
$results = array_fill(0, count($quickpolloptions), 0);
}
/* update the results */
foreach ($_POST['checkboxvote'] as $checkbox) {
$results[$checkbox]]++;
}
/* write them to the file and unlock */
ftruncate($file_handle, 0);
fputs($file_handle, implode(',', $results));
flock($file_handle, LOCK_UN);
fclose($file_handle);
}
I am assuming the second code block is an HTTP endpoint which you hit to save data into your vote_result.txt file.
You're getting the contents of what's currently in that file right now and assigning it to the variable $result - something which you don't need to do since you never actually return it as a response from the script.
All you need is the code that will take the POST parameter array of checkboxvote and save it as a string with commas separating the values. Something like:
if(isset($_POST['checkboxvote'])){
file_put_contents('data/vote_result.txt', implode(',', $_POST['checkboxvote']));
}
You don't need the for loop when writing to your file since implode() already breaks down your array into one string.
Now, when you POST to your script with the following parameter:
checkboxvote[]='owl'
checkboxvote[]='chicken'
checkboxvote[]='deer'
Your vote_result.txt will look like:
owl,chicken,deer
I have a document called subjects.txt in the following format:
DateCreated,Subject,Link
18.10.2015,"Math",http: //address.html
17.10.2015,"English",http: //address.html
18.10.2015,"English",http: //address.html
19.10.2015,"Science",http: //address.html
17.10.2015,"Math",http: //address.html
The file contains URLs of sites created based on a school subject. There can be more than one site for a subject.
The goal is to use PHP to open, read, and display the contents of the file in the following format:
Math
Link 1
Link 2
English
Link 1
Link 2
Science (because there's only one link, the name of the subject is the
link)
So far I've been able to open and read the file:
$file = "./subjects.txt";
$subjects = file_get_contents($file);
I'm having trouble trying to determine how to go about writing the file in specified format.
I've tried using explode to separate the elements with "," - however I don't know where to go from there.
Your input file looks to be in Comma-separated values (CSV) format. PHP has a built-in fgetcsv function designed to make reading CSV data from a file easy.
<?php
$file = './subjects.txt';
$fh = fopen($file, 'r');
if ($fh === false) {
die("Can not read {$file}");
}
$data = array();
while (($row = fgetcsv($fh, 1000, ',')) !== false) {
if ($row[0] === 'DateCreated') {
// Ignore the column header row
continue;
}
list($date, $subject, $link) = $row;
if (!isset($data[$subject])) {
$data[$subject] = array();
}
$data[$subject][] = $link;
}
fclose($fh);
foreach ($data as $subject => $links) {
// TODO: output each subject here
}
Here is another version
<?php
$file = "./subjects.txt";
$h = fopen($file, "r");
if($h !== false) {
$subjects = [];
$data = [];
while(!feof($h)) {
if($line = trim(fgets($h))) {
$line = explode(",", $line);
if(!in_array("DateCreated",$line)) {
array_push($subjects, $line);
}
}
}
fclose($h);
foreach ($subjects as $subject) {
if(!isset($data[$subject[1]])) {
$data[$subject[1]] = [];
}
$data[$subject[1]][] = $subject[2];
}
foreach ($data as $subject => $links) {
if(count($links) == 1) {
echo "<p>$subject</p>\n";
} else {
$i = 1;
echo "<p>$subject</p>\n";
echo "<ul>\n";
foreach ($links as $link) {
echo "<li>link$i</li>\n";
$i++;
}
echo "</ul>\n";
}
}
}
?>
The problem using file_get_contents() is that retrieves all the file contents into $subjects.
You have to use a different approach. For example fgets():
$fp = fopen("./subjects.txt", "r");
if ($fp){
while (($line = fgets($fp)) !== false){
// So here you can treat each line individually.
// You can use explode (";", $line) for example if the line is not empty
}
}
fclose($fp);
Using fgets() will allow you to parse each of the file's lines individually.
As stated doing this with a database would be much easier probably 3 lines of code. Here's one approach you could use though.
$data = '18.10.2015,"Math",http: //address.html
17.10.2015,"English",http: //address1.html
18.10.2015,"English",http: //address2.html
19.10.2015,"Science",http: //address3.html
17.10.2015,"Math",http: //address4.html';
preg_match_all('~^(.*?),"(.*?)",(.*?)$~m', $data, $fields);
array_multisort($fields[2], SORT_STRING, $fields[1], $fields[3]);
$lastcat = '';
foreach($fields[2] as $key => $cat) {
if($cat != $lastcat) {
echo $cat . "\n";
}
$lastcat = $cat;
echo $fields[3][$key] . "\n";
}
Output:
English
http: //address1.html
http: //address2.html
Math
http: //address4.html
http: //address.html
Science
http: //address3.html
The array_multisort is how the categories are grouped.
Here's a regex101 demo of what that regex is doing. https://regex101.com/r/wN3nB2/1
Update for single record check (only ran 1 test on it):
$data = '18.10.2015,"Math",http: //address.html
17.10.2015,"English",http: //address1.html
18.10.2015,"English",http: //address2.html
19.10.2015,"Science",http: //address3.html
17.10.2015,"Math",http: //address4.html';
preg_match_all('~^(.*?),"(.*?)",(.*?)$~m', $data, $fields);
array_multisort($fields[2], SORT_STRING, $fields[1], $fields[3]);
$lastcat = '';
foreach($fields[2] as $key => $cat) {
if((empty($fields[2][($key +1)]) && $cat != $lastcat)|| ($cat != $lastcat && !empty($fields[2][($key +1)]) && $fields[2][($key +1)] != $cat)) {
//single record
echo $cat . $fields[3][$key] . "\n";
} else {
if($cat != $lastcat) {
echo $cat . "\n";
}
$lastcat = $cat;
echo $fields[3][$key] . "\n";
}
}
how can output of inside foreach with serialize store in database? next: called of database?
please give me example.
foreach($upload_data as $file) {
echo serialize($file['file']);
}
output: s:54:"Chrysanthemum6.jpg";s:47:"/Desert6.jpg";
With respect
Something like this?
$result = array();
foreach ($upload_data as $file) {
$result[] = $file['file'];
}
var_dump(serialize($result));
store the serialize in a variable?
$result = '';
foreach($upload_data as $file) {
$result .= serialize($file['file'];
}
echo $result;