Cannot remove image using unlink, are my permissions wrong? - php

I'm trying to use unlink to delete pictures from deleted comments but it's simply not working. The comment from the database gets deleted but the actual picture doesn't. What am I doing wrong? The folder permissions are 755 and the image permissions are 644.
if (loggedin()) {
$dblink = mysqli_connect($DBhostname, $DBusername, $DBpassword, $DBname);
if (!$dblink) {die("Connection error (".mysqli_connect_errno.") " . mysqli_connect_error());}
$commentid = mysqli_real_escape_string($dblink, $_GET['c']);
$qry = "SELECT * FROM comments WHERE id='$commentid' LIMIT 1";
$result = mysqli_query($dblink, $qry) or die(mysqli_error($dblink));
if (mysqli_num_rows($result) > 0) {
$row = mysqli_fetch_assoc($result);
$commenter = $row["commenter"];
$thereisimg = $row["thereisimg"];
$imgtype = $row["imgtype"];
// if logged in email = email of commenter
if ($_SESSION["logged-in"] == $commenter) {
// delete comment
$qry = "DELETE FROM comments WHERE id=$commentid";
$result = mysqli_query($dblink, $qry) or die(mysqli_error($dblink));
// if image, delete image
if ($thereisimg) {
// delete image
$imglink = "/imgs/commentpics/".$commentid.".".$imgtype;
echo $imglink;
unlink($imglink);
}
}
}
}

To diagnose, try one of the following:
Add an error handler to the PHP code to capture the error
Use strace to trace the process and get the exact result of the unlink() system call
Here's a document for (1): http://www.w3schools.com/php/php_error.asp.
To do 2:
strace -e unlink php myScript.php
That assumes the script can be run directly from the command line.
Setting an Error Handler
<?php
function my_error_handler($error_level,$error_message,
$error_file,$error_line,$error_context)
{
echo $error_message;
}
set_error_handler("my_error_handler");

Related

php- How to record which user clicked on a link to download a file

I am trying to record which user has downloaded a file in an SQL database. Every file uploaded has its path displayed as a link on the site, allowing the user to download that file from a folder on the server. I am having trouble figuring out how to record which user has downloaded a file though. How can I query my database that a specific user has clicked a specific link? I have the user id stored as a session variable, so possessing the user id is not a problem. My code to display the downloadable files are as follows:
<?php
session_start();
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "project_website1";
$user_id = $_SESSION[ 'user_id' ];
// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$sql = "SELECT task_id,file, description, title, deadline_claim FROM task";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
echo "<table><tr><th>TITLE</th><th>DESCRIPTION</th><th>DEADLINE</th><th>TASK</th></tr>";
// output data of each row
while($row = $result->fetch_assoc()) {
//echo "<tr><td>" . $row["file"]. "</td><td>" . $row["title"]. "</td><td>" . $row["deadline_claim"]. "</td></tr>";
echo "<tr><td>".$row["title"]."</td><td>".$row["description"]."</td><td>".$row["deadline_claim"]."<td><a href='" .$row["file"]. "'>CLAIM</td></a>";
}
echo "</table>";
} else {
echo "0 results";
}
$conn->close();
?>
If you want it to be purely PHP, as suggested, just use the task_id of the row in your file table. Here is a basic example, noting I have reorganized some elements to help keep your script cleaner. Ideally you will want to keep the functions on a different page and include them when you want to use them. Keeps your script cleaner and more easily readable.:
# Better to make a function/class to do your database so you can reuse it easily.
function getConnection( $servername = "localhost", $username = "root",$password = "",$dbname = "project_website1")
{
# Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
# Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
return $conn;
}
# Make a task retrieval function/class that will deal with getting the rows only
function getTasks($con,$id=false)
{
$sql = "SELECT task_id,file, description, title, deadline_claim FROM task";
# I am assuming your task_id values are numeric, so I don't sanitize here
if ($id) {
if(is_numeric($id))
# Append sql
$sql .= " WHERE `task_id` = '{$id}'";
else
# You shouldn't get this exception unless someone is trying to
# Manually put something else here via injection attempt
throw new Exception("Id must be numeric!");
}
$result = $con->query($sql);
if ($result->num_rows > 0) {
while($row = $result->fetch_assoc()) {
$new[] = $row;
}
}
# Send back rows
return (!empty($new))? $new : array();
}
# This is more of a listener, but it will cut down on some redundant check-script
function getFileId()
{
if(!empty($_GET['file']) && is_numeric($_GET['file']))
return (!empty($_GET['action']) && $_GET['action'] == 'download')? $_GET['file'] : false;
return false;
}
# As noted, you would include the functions here...
session_start();
# Get session id
$user_id = $_SESSION[ 'user_id' ];
# Get the database connection
$conn = getConnection();
# If there is a download
if(!empty($_GET['action']) && $_GET['action'] == 'download') {
# Get the tasks, could be based on id or all
$tasks = getTasks($conn, getFileId());
# Save to the database, make sure that you either bind parameters, or
# check that the values are numeric (if they are supposed to be numeric)
# Also check the count here first for the task before inserting. Make an error if not.
# Usually means user is trying to manipulate the request
$conn->query("INSERT into downloads (`fileid`,`userid`) VALUES('".$tasks[0]['task_id']."','".$user_id."')");
# Download file. If you want to obfuscate the file, you would use
# download headers instead:
# http://php.net/manual/en/function.readfile.php
header('Location: '.$tasks[0]['file']);
# Stop execution
exit;
}
# Get all tasks
$tasks = getTasks($conn);
# If there are rows, output them
if (!empty($tasks)) {
echo "<table><tr><th>TITLE</th><th>DESCRIPTION</th><th>DEADLINE</th><th>TASK</th></tr>";
# output data of each row
foreach($tasks as $row) {
echo "<tr><td>".$row["title"]."</td><td>".$row["description"]."</td><td>".$row["deadline_claim"]."<td><a href='?action=download&file=" .$row["task_id"]. "'>CLAIM</td></a>";
}
echo "</table>";
} else {
echo "0 results";
}
$conn->close();
Final note, I have not tested this, so be aware of that.
your header for calling script in html
<head>
<script laqnguage="javascript" src="myfunction.js" type="text/javascript"></script>
</head>
then in your while loop in php jump out of php
?>
<form name"myform" method="get" action="<? php echo $row["file"]; ?>">
<input type="button" name="name" Value"<? php echo $row["file"]; ?>" onClick="setinsertAction();" />
</form>
then jump into php again
<?php
now create a file called myfunction.js and put this inside
function setinsertAction() {
document.myform.action = "HERE PUT YOUR PHP FILE THAT WILL DO THE QUERY";
document.myform.submit()'
}
if all goes well it should the retrieve the file for download and executed your php script if the you replace your php file for the query in the .js file if it fails let me know

Executing PHP file with crontab

Hello I want executing a php file with crontab. This PHP file makes an update of the MySQL database and when I enter the URL in the browser I can execute the file but not as cronjob.
I add
*/5 * * * * php -f /var/www/html/.../update.php >/dev/null 2>&1
to the crontab, and other cronjobs are working well (3rd part extensions).
Do I need to add some code in my PHP file? Thank you.
Here whats inside the PHP file
<?php
$servername = "";
$username = "";
$password = "";
$dbname = "";
// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$sql = "UPDATE pm_videos SET `description` = REPLACE( `description` ,'Instagram:', '')";
if ($conn->query($sql) === TRUE) {
echo "Record updated successfully with Facebook, ";
} else {
echo "Error updating record: " . $conn->error;
}
$sql = "UPDATE pm_videos SET `description` = REPLACE( `description` ,'Facebook:', '')";
if ($conn->query($sql) === TRUE) {
echo "Record updated successfully with Facebook, ";
} else {
echo "Error updating record: " . $conn->error;
}
$conn->close();
Typically, this is caused by a $PATH issue. Try adding this as the first line of your crontab via crontab -u root -e:
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
If this doesn't fix it, you'll need to look in your code for places where you might be calling external commands, or depending on the values of environment variables. If this doesn't work, please edit your post and show the contents of update.php.

How to delete an image from a folder in PHP

I'm trying to delete an image from data base as well as from a folder in PHP5, but I am unable to delete it. Here is my code:
<?php
$obj=new Crud("localhost","root","","3g");
class Crud{
public $mysqli;
public $data;
public function __construct($host,$username,$password,$db_name) {
$this->mysqli = new mysqli($host, $username, $password, $db_name);
if (mysqli_connect_errno()) {
echo "Error: Could not connect to database.";
exit;
} /*else{
echo"Your Database successfully connected";
}*/
}
public function __destruct() {
$this->mysqli->close();
}
public function read() {
$query="SELECT * FROM fashion";
$result= $this->mysqli->query($query);
$num_result=$result->num_rows;
if ($num_result>0) {
while($rows=$result->fetch_assoc()){
$this->data[]=$rows;
//print_r($rows);
}
return $this->data;
}
}
public function delete($id){
$query="DELETE FROM fashion WHERE id='$id'";
$result= $this->mysqli->query($query) or die(mysqli_connect_errno() . "Data cannot inserted");
if ($result) {
header('location:fashion.php');
}
}
}
?>
By using the above code, the record was deleted only from database, but the image remains in the folder.
To delete an image from your folder you have to use unlink
$file = "yourimage.jpg";
unlink($file);
if image is in any other directory you have to specify full directory Path like
$file = "www/images/yourimage.jpg";
The solution you are looking for is the unlink function which does that - unlinks and deletes a file.
You need the name of the file and the path to the file from the PHP current working directory to make it work. Kamrans answer shows this.
So:
public function delete($id){
$query = "SELECT filepath FROM fashion WHERE id = ? LIMIT 1";
$fileLocale = $this->mysqli->prepare($query);
$fileLocale->bind_param("i",$id);
$fileLocale->execute();
$result = $fileLocale->get_result();
$fileLocale->close();
while ($row = $result->fetch_array(MYSQLI_NUM))
{
/***
* only 1 result is returned so easy to collect
***/
foreach ($row as $r)
{
$filepath = $r;
}
}
unset($r,$row);
/***
$filepath is now the string of the location of the file.
***/
if (unlink($filepath)){
$query="DELETE FROM fashion WHERE id=? LIMIT 1";
$delete = $this->mysqli->prepare($query);
$delete->bind_param("i",$id);
$delete->execute();
$affectedRows = $delete->affected_rows;
if ($affectedRows == 1) {
header('location:fashion.php');
die();
}
when using header always place a die command after it.
use unlink to delete a file, it will return TRUE on success.
filepath is the column in your database that you store the file location.
connect and use the database using OOP principles, use prepared statements rather than queries, there is FAR less risk to you or your code.
Add LIMIT to your SQL statements so if there is an issue, it will not mess up your whole table, for example. A safety measure.
Before you delete the database reference, use it to fill the file name, which is what I am assuming is stored in the database. If $id is the file name, just add it into a system command to remove the file. This assumes Linux.
public function delete($id){
exec('rm /path to file/' . $id);//delete the file via system command.
$query="DELETE FROM fashion WHERE id='$id'";
$result= $this->mysqli->query($query) or die(mysqli_connect_errno() . "Data cannot inserted");
if ($result) {
header('location:fashion.php');
die();
}
}

How download if variable is set, and not download if unset

I'm trying to make an iCalendar file via querying the database, so I don't have to make new iCalendar files with every event created.
<?php
header("Content-type: text/calendar");
$connection = mysqli_connect("localhost", "root", "");
$sql = "SELECT * FROM events WHERE eventID = '{$eventID}'";
$result = mysqli_query($connection, $sql);
$numrows = mysqli_num_rows($result);
// Render iCal file
?>
How to forbid file download if $_GET["eventID"] is not set?
In that case, I want instead of downloading, the visitor to get a blank page for an example.
Stick this at the top:
if (!isset($_GET["eventID"])) {
exit;
}
You should also do something after the SQL query, checking that it has actually returned a result. e.g.
if ($numrows == 0) {
exit;
}
if (!isset($_GET["eventID"])){
echo 'bad';
}else{
// your code here
}
The proper thing to do is the send a 404 Not Found HTTP status code if the URL/entity doesn't exist:
$result = mysqli_query($connection, $sql);
$event = $result->fetch_assoc();
if (!$event) {
header('HTTP/1.0 404 Not Found');
exit;
}
header("Content-type: text/calendar");
echo $event['title'];
..
Here I'm checking whether the event exists in the database. To handle a missing $_GET parameter you could send a 400 Bad Request separately.

Scanning with scanimage from php from a linux host

Here's what the situation is: I am trying to use PHP to call scanimage on a Linux host, then save the resulting file to a web directory for future use.
The below code produces no errors, but when I check out the /tmp directory, file.pnm is blank, and the scanner never starts.
<?php
require('/var/www/olin/includes/functions.php');
$con = connect_db();
//setup the POST variables
if (isset($_POST['submit'])) {
$fname = mysqli_real_escape_string($con, $_POST['fname']);
$lname = mysqli_real_escape_string($con, $_POST['lname']);
$license_no = mysqli_real_escape_string($con, $_POST['license_no']);
$comments = mysqli_real_escape_string($con, $_POST['comments']);
}
if ($license_no == '') {
$license_no = "None on File";
}
if ($fname == '' || $lname == '') {
echo '<h1 class="message">Can\'t submit visitor: you are missing information!</h1>';
} else {
//setup the query and prepare it for exection
$query= "insert into visitors (fname, lname, license_no, redsheet, comments)" .
" values (?, ?, ?, 'Allow', ?) on duplicate key update fname = values(fname)," .
"lname = values(lname), license_no = values(license_no), redsheet = values(redsheet)," .
"comments = values(comments)";
$stmnt= mysqli_prepare($con, $query);
//bind the statement parameters to variables
mysqli_stmt_bind_param($stmnt, "ssss", $fname, $lname, $license_no, $comments );
//execute, then close the statment
if (!mysqli_stmt_execute($stmnt)) {
echo "Failed to ececute the query: " . mysqli_error($con);
header('Refresh: 10; url=http://localhost/olin/visitor.php');
}
}
// we'll `try` to scan the license if the checkbox is selected
if (isset($_POST['pic_id'])) {
// get the info from the db
$query = 'select id from visitors where license_no = "'.$license_no.'"';
$result = mysqli_query($con, $query);
while ($row = mysqli_fetch_array($result)) {
$id = $row['id'];
// set up the path to save the id to (and put path into db for further look up
// and display)
$dir = ( $id % 30 );
$path = '/var/www/olin/images/licenses/'.$dir.'/'.$id.'-license.png';
$path = addslashes(mysqli_real_escape_string($con, $path));
$path1 = '/images/licenses/'.$dir.'/'.$id.'-license.png';
// start the scan, and save image
$command = '/home/jmd9qs/bin/scan.sh "'.$path.'"';
$update = 'update visitors set id_pic = "'.$path1.'" where id="'.$id.'"';
mysqli_query($con, $update) or die ('Error: ' . mysqli_error($con));
exec($command);
header('Location: http://localhost/olin/visitor.php');
}
}
?>
Can anybody provide any hints?
UPDATE:
I have the server running the command now (I know it's failing because of the Apache2 error log).
Here's the error I get:
scanimage: open of device brother3:bus2;dev1 failed: Invalid argument
I've tried adding the www-data user to the scanner and lp groups, but it seems to have no effect... The scanimage command I'm using works under my normal user and as root, so I'm now positive the command I'm using should work. I am still at a loss...
UPDATE (again):
I've fixed some errors in my code... now the server will scan and successfully save images! However, it only works once and then for some odd reason I have to run the scan.sh (which I put the scanimage command into) through my shell for it to run again... otherwise I get the same error message!
Very weird, I have NO clue why, suggestions wanted!

Categories