I have the following script which takes some value from a form and appends to a text file each time new values are entered in the form:
$filename = "nic.txt"; #Must CHMOD to 666, set folder to 777
$text = "\n" . str_pad($fname, 30) . "" . str_pad($lname, 30) . "" . str_pad($tdate, 20) . "" . str_pad($ydept, 30) . "" . str_pad($percentage, 0) . "%";
$fp = fopen ($filename, "a"); # a = append to the file. w = write to the file (create new if doesn't exist)
if ($fp) {
fwrite ($fp, $text);
fclose ($fp);
#echo ("File written");
}
else {
#echo ("File was not written");
}
The issue is, instead of writing to a txt file which isn't secured in storing data, how can I let's say append to a php file so user would need authentication before viewing the file on the web?
I would like some sort of authentication (password/username) in place so not everyone can see it. And with txt file I don't think it's possible.
My SQL writing to data file which I commented out until I find the best option is:
// Write to DB
//$conn = new mysqli('host', 'user', 'pass', 'db');
// check connection
//if (mysqli_connect_errno()) {
// exit('Connect failed: '. mysqli_connect_error());
//}
// store the values in an Array, escaping special characters for use in the SQL statement
//$adds['fname'] = $conn->real_escape_string($fname);
//$adds['lname'] = $conn->real_escape_string($lname);
//$adds['tdate'] = $conn->real_escape_string($tdate);
//$adds['ydept'] = $conn->real_escape_string($ydept);
//$adds['percentage'] = $conn->real_escape_string($percentage);
// sql query for INSERT INTO users
//$sql = "INSERT INTO keepScore ('fname', 'lname', 'tdate', 'ydept', 'percentage' ) VALUES ('". $adds['fname']. "', '". $adds['lname']. "', '". $adds['tdate']. "', '". $adds['ydept']. "', '". $adds['percentage']. "')";
// Performs the $sql query on the server to insert the values
//if ($conn->query($sql) === TRUE) {
// echo 'users entry saved successfully';
//}
//else {
// echo 'Error: '. $conn->error;
//}
//$conn->close();
Keep your text file out of the web server's document root, and use a PHP script to provide authentication/authorization when reading the file.
Take a look at readfile().
PHP files are text files. To achieve what you are asking for, just make $filename end in .php (making sure the data people add is just data and not executable code).
… but editing code programatically is not a great idea. Store your data somewhere outside the web root (possibly in a file, but a database is probably better) and then have your script retrieve it when auth/authz is passed).
A simple solution would be to create a directory with a .txt file in it, which is .htpasswd protected. This way a user needs to authenticate to view the contents, and you are not putting yourself at risk for an untold number of security vulnerabilities.
You can store the files with the .php extension and add header information to serve them as plain text instead of html. Then you can insert a php code at the beginning that will cause the user to authenticate themself.
Related
This code has no error, checked the console no errors, print_r($temp) gives proper result.
print_r($_FILES["file"]["tmp_name"]) gives proper result but the values are no stored in the
phpMyAdmin Db and in the uploaded_videos dir. The last line is also not printed on the screen
<?php
include("database_connection.php");
$allowedExtn = array("mp4","mov","avi","wmv","flv","mpeg");
$temp = explode(".", $_FILES["file"]["name"]);
$extension = end($temp);
$videoname = $_FILES["file"]["name"];
if((($_FILES["file"]["type"]=="video/mp4")
|| ($_FILES["file"]["type"]=="video/mov")
|| ($_FILES["file"]["type"]=="video/avi")
|| ($_FILES["file"]["type"]=="video/wmv")
|| ($_FILES["file"]["type"]=="video/flv")
|| ($_FILES["file"]["type"]=="video/mpeg"))
&& in_array($extension, $allowedExtn))
{
if($_FILES["files"]["error"]>0)
{
echo "Error in Uploading video ". $_FILES["file"]["name"];
}
else
{
move_uploaded_file($_FILES["file"]["tmp_name"], "uploaded_videos/" .
$_FILES["file"]["name"]);
$filepath = "uploaded_videos/" . $_FILES["file"]["name"];
$query = "INSERT INTO video_upload (username, video_name, video_ext,
video_url) VALUES ('Venkat', 'videoname','$extension','$filepath')";
mysql_query($query);
print_r($query);
mysql_close();
echo "Video " .$videoname . " saved.";
}
}
?>
Can anyone please tell me where is the short coming..??
If you are on linux and have access to the filesystem then check the permissions and ownership of the uploaded_videos directory (use ls -la or similar) if you need to change them then look up chmod and chown or use your cpanel? interface.
Make sure also that the directory exists where you think it does (in the same directory as the script you are running).
The first task to sort out is the writing to disk - I'd suggest commenting out the mysql for now.
Also try it with a small file that has a shortish filename with no funny characters or spaces first.
Turn on error reporting in your script error_reporting(E_ALL); ini_set('display_errors',true)
and check the return value of move_uploaded_file
if it is false with no errors then check the file
if it is false with errors then check the filesystem (and the errors)
First of all use MySQLI or PDO for your queries.
$insertQuery = " INSERT INTO `databaseName`.`tableName` (`username`,`video_name`,`video_ext`, `video_url`) VALUES ('Venkat','videoname','$extension','$filepath') ";
$insertQueryResult = $connector->query($insertQuery);
I think you should put the
$filepath = 'uploaded_videos/'.$_FILES['file']['name'];
below of the :
$videoname = $_FILES['file']['name'];
This is just a simple sample for using MySQLI. You can refer to THIS LINK
I'm fairly new to PHP programming and I've looked around but I'm still confused. I'm trying to update the image path in my users table and I'm not quite sure how to do it. This is the code I have for putting the image into the database and it works to insert it in, but I'm not sure how to UPDATE the image picture path in my database to use the newly inserted image as opposed to the one the user selected when they created an account.
// Make sure we didn't have an error uploading the image
($_FILES[$image_fieldname]['error'] == 0)
or handle_error("the server couldn't upload the image you selected.",
$php_errors[$_FILES[$image_fieldname]['error']]);
// Is this file the result of a valid upload?
#is_uploaded_file($_FILES[$image_fieldname]['tmp_name'])
or handle_error("you were trying to do something naughty. Shame on you!",
"upload request: file named " .
"'{$_FILES[$image_fieldname]['tmp_name']}'");
// Is this actually an image?
#getimagesize($_FILES[$image_fieldname]['tmp_name'])
or handle_error("you selected a file for your picture " .
"that isn't an image.",
"{$_FILES[$image_fieldname]['tmp_name']} " .
"isn't a valid image file.");
// Name the file uniquely
$now = time();
while (file_exists($upload_filename = $upload_dir . $now .
'-' .
$_FILES[$image_fieldname]['name'])) {
$now++;
}
// Finally, move the file to its permanent location
#move_uploaded_file($_FILES[$image_fieldname]['tmp_name'], $upload_filename)
or handle_error("we had a problem saving your image to " .
"its permanent location.",
"permissions or related error moving " .
"file to {$upload_filename}");
$insert_sql = "UPDATE users set user_pic_path WHERE user_id = $user_id =
replace(user_pic_path, '$upload_filename', '$upload_filename' );
//insert the user into the database
mysql_query($insert_sql);
</code>
EDIT:
I was missing a " which I fixed and now there is no SQL error, it puts the picture into the database but does not replace the image path in the database. I've been messing with the $insert_sql but it still doesn't update the database with the new image path, what can I do? Here's my new update code:
<code>
$insert_sql = "UPDATE users WHERE user_id = $user_id set user_pic_path =
replace(user_pic_path, '$upload_filename', '$upload_filename')";
</code>
In the final lines, insert a test of your SQL:
$insert_sql = "UPDATE users WHERE user_id = $user_id set user_pic_path = replace(user_pic_path, '$upload_filename', '$upload_filename')";
// check the query
echo $insert_sql."<br />";
//insert the user into the database
mysql_query($insert_sql);
Then you can watch the query your about to run, test it in PHPMyAdmin, work out what it should be. It's worth doing for other key variables as well. Even better, you should write a "debug" function, that logs what's going on in a file on the server so that when an error occurs, you can track details of it, including values of key variables in every file.
So I've made this upload script and to make it more secure, I'm finding out the type of each file.
However, for some reason, the filetype is being echoed back to me!
For example:
image/jpeg; charset=binary Please upload only SWF files!
The echoed string looks same when the upload is successful.
The code:
<?php session_start();
defined('IN_SCRIPT') ? NULL : define('IN_SCRIPT', NULL);
require_once 'inc/db_connect.php';
require_once 'styles/import.php';
$style = new style_class(NULL);
if(!isset($_FILES['file']['tmp_name']) || empty($_FILES['file']['tmp_name'])) die($style->upload_no_parameter());
$filetype = system('file -bi '.$_FILES['file']['tmp_name']);
$filetype = explode(';', $filetype, 1);
if ($filetype[0] != 'application/x-shockwave-flash; charset=binary') die($style->upload_wrong_format());
$sha256 = hash_file("sha256", $_FILES['file']['tmp_name']);
$query = $db->prepare('SELECT id FROM swf WHERE hash = :hash');
$result = $query->execute(array(':hash'=>$sha256));
if ($query->rowCount() != 0) die($style->upload_duplicate());
$query = $db->query('SELECT * FROM swf ORDER BY id DESC LIMIT 1;');
$name = $query->fetch(PDO::FETCH_ASSOC);
$new_name = 'uploads/'.($name['id']+1).'.swf';
if(move_uploaded_file($_FILES['file']['tmp_name'], $new_name)) {
$query = $db->prepare('INSERT INTO swf (uploader, upload_time, hash) VALUES (:id, NOW(), :hash);');
$query->execute(array(':id' => $_SESSION['id'], ':hash'=> $sha256));
echo $style->upload_success();
}
else
echo $style->upload_fail();
?>
I can't see why the script would do such echo...
Thank you!
EDIT:
The style_class was the first place where I looked. This class contains functions returning mainly HTML text. The whole class is auto-generated from database.
I'm copying here the upload_* from the generated file, so you can see:
class style_class{
function upload_no_parameter(){
echo "<b>All parameters must be set!</b>";
}
function upload_fail(){
echo "<b>There was an error, please try again.</b>";
}
function upload_success(){
echo "<b>Your SWF has been uploaded!</b>";
}
function upload_duplicate(){
echo "<b>File already exists!</b>";
}
function upload_wrong_format(){
echo "<b>Please upload only SWF files!</b>";
}
}
Thank you!
I'd bet die($style->upload_wrong_format()) is causing the issue. Check that function.
You've got some very nasty logic bugs in your code:
1) Assuming the file upload succeeded. Proper error handling goes like this:
if ($_FILES['file']['error'] !== UPLOAD_ERR_OK) {
die("File upload failed with error code " . $_FILES['file']['error']);
}
Checking any of the other fields in any file upload is not proper - those fields can still be present and populated even for a failed upload. The error codes are documented here: http://php.net/manual/en/features.file-upload.errors.php
2) you're using exec() and calling file to determine mimetypes. Why? PHP has the finfo library for just this purpose: http://php.net/manual/en/book.fileinfo.php it uses the same magic numbers library as file and doesn't require an exec() call to work.
3) You have a very racey error-prone method of getting an ID number for your swf:
$query = $db->query('SELECT * FROM swf ORDER BY id DESC LIMIT 1;');
$name = $query->fetch(PDO::FETCH_ASSOC);
$new_name = 'uploads/'.($name['id']+1).'.swf';
Nothing says that another script cannot execute AND complete in the time you fetch this ID number and the time you complete thigns here. A proper method is to start a transaction, insert a skeleton record into the DB, retrieve its auto_increment primary key, then update the record and do your file moves with that id. It'll be guaranteed to be unique, whereas at some point your code WILL fail and stomp on another upload.
I'm trying to create a download link in PHP so you can download the information in a table. I just started writing it and have run into a snag. Here is what I have so far:
<?php
$sql = "SELECT * FROM " . $survey . ";";
$result = mysql_query($sql)
or die(mysql_error());
$row = mysql_fetch_assoc($result);
$something = "This is text";
$myFile = "data.txt";
$fh = fopen($myFile, 'w') or die("can't open file");
$download_data = "";
foreach ($row as $k=>$v){
$download_data .= $k . "=" . $v . "\n";
}
fwrite($fh, $download_data);
fclose($fh);
echo $download_data;
?>
Download
It is just supposed to show something like Code = 1 Name = John etc. When I open the txt file, it simply says Resource id #7. The weird part is, when I echo $download_data, it looks correctly in the web page. Is there something special I have to do with fwrite in order to get the whole string into the text file
(Note: I have used both mysql_fetch_array and mysql_fetch_assoc and both have the same result. Also, if I simply declare a variable like $test = "this is a test"; it works).
Edit:
I have tried commenting out all other code in the script and I get the same result. Printing $download_data shows the right result, but the text file is still only showing Resource id #7. I've even tried deleting the txt file and when it is recreated, it does the same thing.
You're almost certainly not showing us the whole picture with your example code.
You are likely writing one of these things to the file:
The file handle, $fh
The result returned from mysql_query()
Check you're not mixing up $result and $row. Or even better, post all of your code.
Ok, this one is driving me nuts. I have a backend file uploader that uploads .jpg files to the server. Then I want to upload the filename(s) of the .jpgs to my database. So when the page loads I can add the filename from the database and the pictures will display on the page. This works fine, but I also need to be able to update the files and the filenames in the database. If the user changes all the files and file names everything is fine. But if the user wishes to change only one or two file(s) and filename(s) the MySql update statement ends up having some of the variables empty thereby effectively deleting the existing filenames in the record instead of leaving them alone. As usual I have searched stackoverflow and google before asking for help and I have not found anything that is really pertinent. Here is the applicable code.
<?php
session_start();
$id = $_SESSION['id'];
//This is the directory where images will be saved
$target = "imgs/";
// "http://www.surfcup.com/travel_site/images/ ";
$targetlogo = $target . basename( $_FILES['imageLogo']['name']);
$targetpic1 = $target . basename( $_FILES['image1']['name']);
$targetpic2 = $target . basename( $_FILES['image2']['name']);
$targetpic3 = $target . basename( $_FILES['image3']['name']);
$targetpic4 = $target . basename( $_FILES['image4']['name']);
$targetpic5 = $target . basename( $_FILES['image5']['name']);
//This gets all the other information from the form
$logo=($_FILES['imageLogo']['name']);
$pic1=($_FILES['image1']['name']);
$pic2=($_FILES['image2']['name']);
$pic3=($_FILES['image3']['name']);
$pic4=($_FILES['image4']['name']);
$pic5=($_FILES['image5']['name']);
// Connects to Database
mysql_connect("localhost", "surfcup_HotAdmin","password") or die ('I cannot connect to the database because: ' .mysql_error());
mysql_select_db("surfcup_hotels") or die('I cannot connect to the database because: .mysql_error());
$query="UPDATE Hotels
SET
hotel.imageLogo = '".$logo."',
hotel.image1 = '".$pic1."',
hotel.image2 = '".$pic1."',
hotel.image3 ='".$pic1."',
hotel.image4 = '".$pic1."',
hotel.image5 = '".$pic1."'
WHERE Hotels.id='".$id."'";
mysql_query($query) or die ('Error Updating Hotel '.mysql_error());
//stuff to upload the files below
?>
I think I either need to check if the variables are null and somehow not up load them or stop the database from accepting null entries. The later though would make the user have to add 6 files when he/she creates a record. What if they only had 5 or 3? I can't seem to get my head around how I would check if the variables are null and only upload the ones with filenames in them in the UPLOAD statement. Thanks again, in advance, for all your help.
Dave
I think a better way of doing this is to build your query dynamically. For example:
$images = array();
$images[] = ($_FILES['imageLogo']['name']);
$images[] = ($_FILES['image1']['name']);
$images[] = ($_FILES['image2']['name']);
$images[] = ($_FILES['image3']['name']);
$images[] = ($_FILES['image4']['name']);
$images[] = ($_FILES['image5']['name']);
// Looping index to determine which hotel image it is
$index = 0;
// Start building query
$query = "UPDATE Hotels SET hotel.imageLogo = '".$images[0]."'";
// Loop through images and check if empty string
foreach($images as $image)
{
if(!empty($image) && $index != 0)
{
// Image name found, add to query
$query .= " hotel.image".$index." = '".$image."',";
}
// First hotel image iteration needs to be 1
$index++;
}
// Finish query
$query .= " WHERE Hotels.id='".$id."'";
You can try this. Basically it checks if the value is empty. If it is not, then it adds the value to the array. At the end we implode the array into a string that we will add to the your query. In the example I only did a few of the images, but you should get the point. It should work barring syntax errors in my code.
Although I will say that this is not the best way to do it. You can definitely improve on this and make it more secure and efficient.
$uploaded_images = array();
if(!empty($logo)){
$uploaded_images[] = "hotel.imageLogo = '".$logo."'";
}
if(!empty($pic1)){
$uploaded_images[] = "hotel.image1 = '".$pic1."'";
}
if(!empty($pic2)){
$uploaded_images[] = "hotel.image2 = '".$pic2."'";
}
$values_to_set = implode(', ', $uploaded_images);
$query= "UPDATE Hotels SET " . $values_to_set . " WHERE Hotels.id='" . $id . "'";