I've been working on this problem for a few hours and have used many resources from the web and stack overflow, but I can't seem to get past this last thing. I'm in the middle of attempting to get the contents of a csv file and store them in an array and print the results on another page via a session.
index.php (Shows form for uploading file)
<html>
<form action="http://mysite.org/~me/upload.php" method="POST" enctype="multipart/form-data">
<input type="file" name="file"><br />
<input type="submit" value="Now upload it!">
</form>
</html>
upload.php (if CSV, output filesize, print_r the array that should contain all data)
<?php
session_start();
if (($_FILES["file"]["type"] == "application/vnd.ms-excel"))
{
if ($_FILES["file"]["error"] > 0)
{
echo "Return Code: " . $_FILES["file"]["error"] . "<br />";
}
else
{
echo "Size: " . ($_FILES["file"]["size"] / 1024) . " Kb<br />";
$file = fopen($_FILES["file"]["tmp_name"], 'r');
while (($line = fgetcsv($file)) !== FALSE) {
//$line is an array of the csv elements
print_r($line);
$_SESSION['line']=$line;
}
fclose($file);
}
}
else
{
echo "Invalid file";
}
echo "<a href='http://mysite.org/~me/yes.php'>Yes</a>";
?>
yes.php
<?php
session_start();
$data = $_SESSION['line'];
print_r($data);
?>
The print_r from the upload page should be the same as the print_r from the yes page, but it is not. It is only showing the last array. I don't understand how I would go about this problem.
As a side note: I've only been programming in php for about 2 weeks so please be thoughtful enough to explain your answers. It really helps! Thanks =)
You need to append instead of overwrite $_SESSION['line'].
Instead of:
$_SESSION['line'] = $line; // overwriting $_SESSION['line'] w/ each iteration
You need to:
$_SESSION['lines'][] = $line; // pushes the line to an array
Then on, yes.php, you can:
session_start();
$data = $_SESSION['lines'];
print_r($data);
Related
Hello I am trying to check the size of a file in PHP but it does not seem to work. My input page is
<html>
<title>File Upload</title>
<body>
<h1>
Upload Files
</h1>
<form action = "yes.php" method = "POST" enctype="multipart/form-data">
Upload your file
<input type = "file" name = "file" id = "fileToUpload">
<input type ="submit" name ="submit" value = "Start Upload">
</form>
</body>
</html>
This is the yes.php
<?php
$filename = $_FILES["file"]["name"];
$filesize = $_FILES["file"]["size"];
if (isset($_POST["submit"])) {
echo "$filename";
echo "\n$filesize";
if ($filesize < 4) {
echo "good";
} else {
echo "bad";
}
}
?>
It outputs
disc.mp4 0good
The file disc.mp4 is 5.8 MB but it returns as 0 MB even when it correctly identifies the name of the file. How can I fix this?
The different keys of the $_FILES array are explained here. Your code is taking for granted that every script invocation contains a valid file upload, which of course if often untrue: just open yes.php in your browser and you'll see (or you should see) lots of error messages. You're also making a strange check: the upload is valid if the file size is 0 to 3 bytes :-!
The bare minimum you need is:
Accommodate the fact that $_FILES['file'] may or may not exist.
Verify whether the upload succeeded.
If you expect a 5.8 MB file, don't require it to have an arbitrary smaller size.
Following you code style, I'd be something like:
<?php
$error = $_FILES["file"]["error"] ?? null;
$filename = $_FILES["file"]["name"] ?? null;
$filesize = $_FILES["file"]["size"] ?? null;
$expected_size = 5.8 * 1024 * 1024; # Assuming you want to enforce this for some reason
if ($error === UPLOAD_ERR_OK) {
echo "$filename";
echo "\n$filesize";
if ($filesize != $expected_size) {
echo "good";
} else {
echo "bad";
}
} elseif($error !== UPLOAD_ERR_NO_FILE) {
echo "upload failed";
}
I have a a script that can upload the contents of a CSV file and download the links to a local directory, the CSV file i need to upload to it is about 4056 lines long and 4056 FTP downloads, the script works fine but the web server times out when i use it.
even tried set_time_limit(0);
is there a way i could session the script and loop the process so it could do it's job for a few hours without interruptions.
<?php
/**
* Please change your upload directory according to your needs. Make sure you include the trailing slash!
*
* Windows C:\tmp\
* Linux /tmp/
*/
$uploaddir = '/tmp/';
if(isset($_FILES['userfile']['name'])){
// Read uploaded file
$lines = file($_FILES['userfile']['tmp_name']);
echo "Reading file ... <br/>";
$linecount = 0;
foreach($lines as $line ){
echo ++$linecount . ". FTP Url is : " .$line . "<br/>";
echo " Downloading " . $line . "<br/>";
$parsed_url_values = parse_url($line);
//TODO perhaps do a validation of the ftp url??
if($parsed_url_values['scheme'] == 'ftp'){
// set up basic connection
$conn_id = ftp_connect($parsed_url_values['host']);
// login with username and password
$login_result = ftp_login($conn_id, $parsed_url_values['user'], $parsed_url_values['pass']);
ftp_pasv($conn_id, true);
$path = rtrim($parsed_url_values['path'], '_');
$filename = basename($path);
if (ftp_get($conn_id, $uploaddir . $filename, $path , FTP_BINARY)) {
echo " Successfully downloaded the file " .$line . "<br/>";
} else {
echo " Could not save the file to " . $line . ". Please verify the url is correct and the file exists.<br/>";
}
} else {
echo " Sorry. This script was made for FTP downloads only.";
}
}
}
?>
<form enctype="multipart/form-data" action="" method="post">
<input type="hidden" name="MAX_FILE_SIZE" value="30000" />
Select the file to upload : <input name="userfile" type="file" />
<input type="submit" value="Upload" />
</form>
You need to increase the execution time of your script by using max_execution_time. You can use this example, place it on top of your script:
<?php
ini_set('max_execution_time', 300); //300 seconds = 5 minutes
.. The rest of your script
Hope this will help you!
In my practice I often use step by step loading if i can't load data via cron or php cli.
Something like that (not tested):
<?php
$newFileName = '/path/to/file.csv';
$line = isset($_REQUEST['csvline']) ? (int) $_REQUEST['csvline'] : 0;
$handle = fopen($newFileName, "r");
//10 seconds for each step
$stepTime = 10;
$startTime = time();
$lineCounter = 0;
while (($fileop = fgetcsv($handle)) !== false)
{
//already loaded lines
$lineCounter++;
if ($lineCounter <= $line) continue;
//here goes your script logic
//stops when time goes out
if (time() - $startTime >= $stepTime) break;
}
//next you need to query this script again
//using js maybe (window.location or ajax call)
//so you can see loading progress or any other useful information
//like
if (!feof($handle)) {
echo "<script>window.location = '/your.php?csvline={$lineCounter}'<script>";
}
//you even can start loading from last line before script fails
But i'm sure that using cron is the best solution for your problem.
<textarea placeholder="Source code of file" class="source">
<?php echo ($thesource) ?>
</textarea>
<?php
$blacklist = array("one.jps", "two.txt", "four.html");
if ($handle = opendir('.')) {
while (false !== ($entry = readdir($handle))) {
if ($entry != "." && $entry != ".." && !in_array($entry, $blacklist)) {
$thesource = file_get_contents($entry);
echo "<div class='post'
<p>$entry</p>
</div>
";
}
}
closedir($handle);
}
?>
Output:
<textarea placeholder="Source code of file" class="source">
<!DOCTYPE html>
<html>
etc
etc
</body>
</html>
</textarea>
<p>ok.html</p>
<p>source.php</p>
<p>sub.html</p>
<p>stylesheet.css</p>
As confusing this may look, let me try to explain what I want to achieve.
Lets say that there are some files in a directory (4 in this case). The PHP code I am using will echo out all those 4 files onto the page that the PHP code is on - it excludes everything in the blacklist. So it will look a little something like this:
<p>ok.html</p>
<p>source.php</p>
<p>sub.html</p>
<p>stylesheet.css</p>
There is also a textarea:
<textarea placeholder="Source code of file" class="source">
<?php echo ($thesource) ?>
</textarea>
This textarea will have a value of $thesource. Whatever is in the $thesource variable will appear in the textarea.
To define the $thesource variable, this is the PHP code I am using:
$thesource = file_get_contents($entry);
Note that $entry is all the files that are echoed out onto the page (as explained above - 4 files in this case)
I am trying to make it so that, whenever a user clicks on one of the files:
<p>ok.html</p>
<p>source.php</p>
<p>sub.html</p>
<p>stylesheet.css</p>
When the user clicks on those listed above, it will display the source code of the clicked file in the textarea.
The current source code I am using, only echo's out the source code of the current file containing the PHP code.
How would I achieve this? Thanks - and if you are still unsure of what I am trying to achieve, then please ask!
This should work for you:
First i get all files in a directory with glob() which aren't in the blacklist. After that i print a list which you can click on it.
If you click on it the file get's included and displayed in the textarea.
<?php
$blacklist = array("one.jps", "two.txt", "four.html");
$files = array_diff(glob("*.*"), $blacklist);
foreach($files as $file)
echo "<div class='post'><a href='" . $_SERVER['PHP_SELF'] . "?file=" . $file . "'><p>" . $file . "</p></a></div>";
if(!empty($_GET["file"]) && !in_array($_GET["file"], $blacklist) && file_exists($_GET["file"]))
$thesource = htmlentities(file_get_contents($_GET["file"]));
?>
<textarea rows="40" cols="100" placeholder="Source code of file" class="source"><?php if(!empty($thesource))echo $thesource; ?></textarea>
am having some trouble with PHP on the webserver I am using.
I am sure the answer is obvious but for some reason it is eluding me completely.
I have a php file which uploads two files, a before and an after shot of the client.
The script on my server(localhost) works fine, it uploads the files, renames the files to a timestamp and puts the images into there folders for further sorting by another script.
Yet when I upload it to the webserver, and some files work (i.e mel.jpg, test.jpg) but files like IMG_0042.jpg do not work, Im sure the answer is something simple, but is completely eluding me.
Im thinking the underscore may have something to do with it, but cannot for the life of my figure it out, any help greatly appreciated,
thanks very much.
<?php
if(!isset($_COOKIE['auth'])) {
header("Location: login12.php");
exit();
}
$page_title="test";
include('header.html');
// Upload and Rename File
if (isset($_POST['submitted'])) {
$filenamebef = $_FILES["uploadbef"]["name"];
$filenameaft = $_FILES["uploadaft"]["name"];
$file_basename_bef = substr($filenamebef, 0, strripos($filenamebef, '.'));
$file_basename_aft = substr($filenameaft, 0, strripos($filenameaft, '.'));
// get file extention
$file_ext_bef = substr($filenamebef, strripos($filenamebef, '.'));
$file_ext_aft = substr($filenameaft, strripos($filenameaft, '.'));
// get file name
$filesize_bef = $_FILES["uploadbef"]["size"];
$filesize_aft = $_FILES["uploadaft"]["size"];
$allowed = array('image/pjpeg','image/jpeg','image/JPG','image/X-PNG','image/PNG','image /png','image/x-png');
if ((in_array($_FILES['uploadbef']['type'], $allowed)) && in_array($_FILES['uploadaft']['type'], $allowed)) {
if (($filesize_bef < 200000) && ($filesize_aft < 200000)){
// rename file
$date = date("mdy");
$time = date("His");
$timedate = $time . $date;
$newfilenamebef = $timedate . $file_ext_bef;
$newfilenameaft = $timedate . $file_ext_aft;
if ((file_exists("upload/images/before" . $newfilenamebef)) && (file_exists("uploads/images/after" . $newfilenameaft))) {
// file already exists error
echo "You have already uloaded this file.";
} else {
move_uploaded_file($_FILES["uploadbef"]["tmp_name"], "uploads/images/before/" . $newfilenamebef) && move_uploaded_file($_FILES["uploadaft"]["tmp_name"], "uploads/images/after/" . $newfilenameaft);
echo "File uploaded successfully.";
}
}
} elseif ((empty($file_basename_bef)) && (empty($file_basename_aft))) {
// file selection error
echo "Please select a file to upload.";
} elseif (($filesize_bef > 200000) && ($filesize_aft > 200000)) {
// file size error
echo "The file you are trying to upload is too large.";
} else {
// file type error
echo "Only these file typs are allowed for upload: " . implode(', ',$allowed);
unlink($_FILES["uploadbef"]["tmp_name"]);
unlink($_FILES["uploadaft"]["tmp_name"]);
}
}
echo $newfilenamebef;
echo $newfilenameaft;
?>
<form enctype="multipart/form-data" action="uploading.php" method="post">
<input type="hidden" value="MAX_FILE_SIZE" value="524288">
<fieldset>
<legend>Select a JPEG or PNG image of 512kb or smaller to be uploaded : </legend>
<p><b>Before</b> <input type="file" name="uploadbef" /></p>
<p><b>After</b> <input type="file" name="uploadaft" /></p>
</fieldset>
<div align="center"><input type="submit" name="submit" value="Submit" /></div>
<input type="hidden" name="submitted" value="TRUE" />
</form>
<?php
include('footer.html');
?>
You should but these two lines at the top of your index.php or bootstrap.php :
error_reporting( -1 );
ini_set( "display_errors" , 1 );
And see if some error messages turn up.
It is quite possible that problem is caused by wrong file permissions.
At a quick guess I would say that your localhost is not case sensitive, whereas your webserver is.
In other words, on your localhost IMG_12345.JPG is the same as img_12345.jpg. On your webserver, though, they are treated differently.
Without any actual reported errors, it's hard to be certain, but this is a common problem.
You're not checking for valid uploads properly. Something like the following would be FAR more reliable:
// this value is ALWAYS present and doesn't depend on form fields
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$errmsgs = array();
if ($_FILES['uploadbef']['error'] !== UPLOAD_ERR_OK) {
$errs++;
$errmsgs[] = "'uploadebef' failed with code #" . $_FILES['uploadebef']['error'];
}
if ($_FILES['uploadaft']['error'] === UPLOAD_ERR_OK) {
$errs++;
$errmsgs[] = "'uploadeaft' failed wicode #" . $_FILES['uploadeaft']['error'];
}
if (count($errmsgs) > 0) {
print_r($errmsgs);
die();
}
... process the files here ...
}
As well, why re-invent the wheel to split up the file names?
$parts = path_info($_FILES['uploadaft']['name']);
$basename = $parts['basename'];
$ext = $parts['extension'];
I really want to know how am I gonna get the full filepath when I upload a file in PHP?
Here's my my problem...
I am importing a csv file in PHP. Uploading a file isn't a problem but the function used to import csv files which is fgetcsv() requires fopen. fopen is the one giving me a headache because it requires an exact filepath which means that the file should be in the same directory with the php file. What if the user gets a file from a different directory.
Here's my codes:
index.php:
<form action="csv_to_database.php" method="POST" enctype="multipart/form-data">
<input type="file" name="csv_file" />
<input type="submit" name="upload" value="Upload" />
</form>
csv_import.php:
<?php
if ($_FILES['csv_file']['error'] > 0) {
echo "Error: " . $_FILES['csv_file']['error'] . "<br />";
}else{
if (($handle = fopen($_FILES['csv_file']['name'], "r")) !== FALSE) {
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
for ($c=0; $c < count($data) ; $c++) {
echo $data[$c] . " ";
}
echo "<br />";
}
fclose($handle);
}
}
?>
fopen here can only get the filename which is passed by the variable $_FILES['csv_file']['name']. I was trying to get any functions to get the full filepath for $_FILES in the internet but can't find any.
I am very new to web development so pls be patient. Pls answer as simple as possible... Pls help...
The ['name'] refers to the original filename on the users computer. That's no use to you, in particular because it might be empty. (Or it can contain fake values, causing a directory traversal exploit. So, just avoid it.)
You need to use the ['tmp_name'] which is a server-absolute path like /tmp/upload85728 that can be used for fopen() or move_uploaded_file().
I was able to successfully imported csv file and stored it in the mysql database.
Here are the the codes (actually its almost the same as my question with some slight changes with great effect):
index.php:
<form action="csv_import.php" method="POST" enctype="multipart/form-data" >
<input type="file" name="csv_file" />
<input type="submit" name="upload" value="Upload" />
</form>
csv_import.php:
<?php
if ($_FILES['csv_file']['error'] > 0) {
echo "Error: " . $_FILES['csv_file']['error'] . "<br />";
}else{
if (($handle = fopen($_FILES['csv_file']['tmp_name'], "r")) !== FALSE) {
$dbconn = mysql_connect("localhost", "root", "") or die("Couldn't connect to server!");
mysql_select_db("csv_test") or die("Couldn't find database!");
$ctr = 1; // used to exclude the CSV header
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
if ($ctr > 1) mysql_query("INSERT INTO ninja_exer (name, village, country) VALUES ('$data[1]', '$data[2]', '$data[3]')");
else $ctr++;
}
fclose($handle);
}
}
?>
you need to define a path into your config file or wherever you want to use and then that variable whatever you define, you can use in you project.
i.e: define('FILE_UPLOADED_PATH','folder1/folder2/so on');
so after the put this code your full filepath would be-
FILE_UPLOADED_PATH.$_FILES['csv_file']['name'];
you can use above code as example.
Thanks.