symlink directory - php

Can I get an eyeball on my symlink?
I'm trying to download a file from one directory, while the file actually exists in another.
I've got the actual file, and the symlink in seperate subdirectories, but both reside in the public html(both are web accessible).
I've verified the file and file location on my (shared Linux) server by going to the file directly.
The link is being created (I've used readlink, is_link, and linkinfo), and I can see it when I FTP in.
I believe I am probably just having a misunderstanding of the directory structure.
I put the file here: ./testdownload/
I put the symlink here: ./testDelivery/
<?php
$fileName = "testfiledownload.zip";//Name of File
$fileRepository = "./testdownload/";//Where the actual file lives
$downloadDirectory = "./testDelivery/";//Where the symlink lives
unlink($downloadDirectory . $fileName); // Deletes any previously exsisting symlink (required)
symlink($fileRepository . $fileName, $downloadDirectory . $fileName);
$checkLink = ($downloadDirectory . $fileName);
if (is_link($checkLink))
{
echo ("<br>Symlink reads: " .readlink($checkLink) . "<br>");
echo ("<br>LinkeInfo reads: " . linkinfo($checkLink));
}
?>
<p><a href="<?php echo ("/testDelivery/" . $fileName); ?>"</a>SymLink</p>
<p><a href="<?php echo ("/testdownload/" . $fileName); ?>"</a>regular link</p>
Everything looks right to me....but the link won't work.
Help?
Ultimately, I will put the source data outside the public area...this is just for testing.
(I'm trying to find a better solution for download than chunking out fread which fails for poor connections. (200-400MB files))

My problem (appears) to be not providing the absolute path for the symlink.
I've added the absolute path below to the same code above, to give a working copy:
<?php
$absolutepath = ( $_SERVER['DOCUMENT_ROOT']);
$fileName = "testfiledownload.zip";//Name of File
$fileRepository = "/testdownload/";//Where the actual file lives
$downloadDirectory = "/testDelivery/";//Where the symlink lives
unlink($absolutepath .$downloadDirectory . $fileName); // Deletes any previously exsisting symlink (required)
symlink($absolutepath . $fileRepository . $fileName, $absolutepath. $downloadDirectory . $fileName);
$checkLink = ($absolutepath . $downloadDirectory . $fileName);
if (is_link($checkLink))
{
echo ("<br>Symlink reads: " .readlink($checkLink) . "<br>");
echo ("<br>LinkeInfo reads: " . linkinfo($checkLink));
}
?>
<p><a href="<?php echo ("/testDelivery/" . $fileName); ?>"</a>SymLink</p>
<p><a href="<?php echo ("/testdownload/" . $fileName); ?>"</a>regular link</p>
This original post, is a duplicate (though I didn't see it until now)
Create a valid symlink for PHP file
(Most of the answers given for that question were wrong however--but the original poster figured it out, and it worked for me too)

Related

PHP: File cannot be downloaded ("404 Not Found" message)

I am working on a website of a client for which I didn't write the code. I have troubles making files downloadable.
It is about a subdomain where users can download course files.
The website files are contained in the folder "courses" (on the root level).
The file for displaying the downloadable course files is contained in
"courses/displayfiles.php".
The downloadable files are contained in a folder in "courses/downloadfolder". Inside this folder, each user has his own
files folder which as its name has the user id.
displayfiles.php: The following code successfully displays all files that can be downloaded by the logged-in user:
$path = "downloadfolder/" . $_SESSION['userId'] . "/";
$files = array();
$output = #opendir($path) or die("$path could not be found");
while ($file = readdir($output)) {
if (($file != "..") and ($file != ".")) {
array_push($files, $file);
}
}
closedir($output);
sort($files);
foreach ($files as $file) {
echo '<a class="imtext" href="downloadfolder/' . $_SESSION['userId'] . '/' . $file . '/">' . $file . '</a><br/>';
}
So what does not work about this code: When a user clicks on a file, I get a "404 Not Found" message that the file was not found. How can this be?
Why does displaying the files totally works fine, but at the same time I get a 404 error when clicking a file? The files path ($path) must be correct, or not? What further investigations do I need to take in order to solve this problem?
* UPDATE *
I decided to modify the files loop as followed (changing the href):
foreach ($files as $file) {
echo '<a class="imtext" href="http://'.$_SERVER['HTTP_HOST']. '/downloadfolder/' . $_SESSION['courseId'] . '/' . $file . '/">' . $file . '</a><br/>';
}
Still, when I click on a file, I get a 404 Not Found error. How can this be?
You have to look where the webroot of your page is, where the php file generating the list is located and wherer the files are.
Your generated link is relative to the php file generating the link, which might not be corresponding to the URL in the browser. I'd try to make this link relative to the webroot (note the leading slash!)
echo '<a class="imtext" href="/courses/downloadfolder/' . $_SESSION['userId'] . '/' . $file . '/">' . $file . '</a><br/>';
If that guessed solution doesn't work please provide the current URL of the page where this links are generated and one generated link, so we can help you better.

Images are not shown and file name changes when uploaded to the database

I can't get the picture to display/show when viewing, although the files are already stored in the database (table 'menu') http://i.imgur.com/wo1w90H.png. Also when I upload the images all at once, their file name would change automatically. I don't know how and why this happens. I use array to upload multiple images.
if (isset($_POST["Submit"])) {
--some code here--
if (isset($_POST["id_list"])) {
// if id list available
foreach($_POST["id_list"] AS $id) {
--some code here--
/* Handle file upload */
if ($_FILES['upload']['error'][$id] == 'UPLOAD_ERR_OK') {
$path = "images/newmenu/";
$path_parts = pathinfo($_FILES["upload"]["name"][$id]);
$extension = $path_parts['extension'];
$picture = md5(uniqid()) . "." . $extension;
if (move_uploaded_file($_FILES['upload']['tmp_name'][$id], $path . "/" . $picture)) {
$update = " UPDATE menu
SET MenuPicture='$picture'
WHERE MenuID=$id";
$mysqli->query($update) or die(mysqli_error($mysqli));
}
}
}
}
}
}
Below is the form and yes it does include enctype="multipart/form-data"
<input type="file" multiple name="upload[' . $id . ']" value="' . $record["MenuPicture"] . '">
Filename changes because you are generating it this way
$picture = md5(uniqid()) . "." . $extension;
uniqid() is based on current time and hashing it will cause the filename to change everytime
When I upload the images all at once, their file name would change automatically
It was due to this:
$picture = md5(uniqid()) . "." . $extension;
// And later
move_uploaded_file($_FILES['upload']['tmp_name'][$id], $path . "/" . $picture)
Basically, you are moving your uploaded file to a new filename for your image file, which is generated using uniqid() and hashed with md5(), with the file extension appended at the end.
I can't get the picture to display/show when viewing
How are you trying to display the picture? Is it from web browser, or you go straight to the directory and open from there? What error(s) did you get, if any?
Actually, have you tried to go to the directory and see whether the file is created inside the images/newmenu/ directory?
Also, for the target upload directory, you might want to append it with $_SERVER['DOCUMENT_ROOT'] so that the target directory is not dependent on where your script is located, but it's always based on the root.
By the way, you might know already, but there is an entry in PHP manual page on uploading multiple files

use file_exists() to check wordpress uploads folder

I have created a directory in Wordpress uploads folder for end user to bulk upload photos via ftp. Images are numbered 1.jpg, 2.jpg... etc. I've generated the image urls successfully, but now I want to test for empty urls - i.e. if "8.jpg" doesn't exist, show a placeholder image from the theme's images folder instead.
I'm trying to use file_exists(), but this returns false every time and always displays the placeholder image. Any suggestions would be appreciated.
<?php while ( have_posts() ) : the_post();
// create url to image in wordpress 'uploads/catalogue_images/$sale' folder
$upload_dir = wp_upload_dir();
$sub_dir = $wp_query->queried_object;
$image = get_field('file_number');
$image_url = $upload_dir['baseurl'] . "/catalogue_images/" . $sub_dir->name . "/" . $image . ".JPG"; ?>
<?php if(file_exists($image_url)){
echo '<img src="' . $image_url . '" alt="" />';
} else {
//placeholder
echo '<img src="' . get_bloginfo("template_url") . '/images/photo_unavailable.jpg" alt="" />';
} ?>
<?php endwhile; ?>
The PHP file_exists function mainly expects an internal server path to the file to be tested. This is made obvious with the example.
Fortunately, we see that wp_upload_dir() gives us several useful values:
'path' - base directory and sub directory or full path to upload directory.
'url' - base url and sub directory or absolute URL to upload directory.
'subdir' - sub directory if uploads use year/month folders option is on.
'basedir' - path without subdir.
'baseurl' - URL path without subdir.
'error' - set to false.
I've bolded what we want to use. Using these two values, you have to generate two variables, one for the external URL and one for the internal file path:
$image_relative_path = "/catalogue_images/" . $sub_dir->name . "/" . $image . ".JPG";
$image_path = $upload_dir['basedir'] . $image_relative_path;
$image_url = $upload_dir['baseurl'] . $image_relative_path;
Then use file_exists($image_path) instead of file_exists($image_url).
Note
As with the PHP notes on PHP >= 5.0.0, you can indeed use file_exists with some URLs, however the http:// protocol is not supported for the stat() function (which is what file_exists uses.)
You have to use an internal path for checking if a file exists.
So use $upload_dir['path'] instead $upload_dir['baseurl']
[path] - base directory and sub directory or full path to upload
directory.
http://codex.wordpress.org/Function_Reference/wp_upload_dir

Retrieve original uploaded filename using php on OpenShift

I would like to check that a file uploaded to my OpenShift app has a text extension (.txt or .tab). Following some advice given here I wrote the following code, with echoes added to help debug:
$AllowedExts = array('txt','tab');
echo "AllowedExts: " . $AllowedExts[0] . " and " . $AllowedExts[1] . "<br>";
$ThisPath = $_FILES['uploadedfile']['tmp_name'];
echo "ThisPath: " . $ThisPath . "<br>";
$ThisExt = pathinfo($ThisPath, PATHINFO_EXTENSION);
echo "ThisExt: " . $ThisExt . "<br>";
if(!in_array($ThisExt,$AllowedExts) ) {
$error = 'Uploaded file must end in .txt or .tab';
}
echo "error echo: " . $error . "<br>";
On uploading any file, the echoed response was:
AllowedExts: txt and tab
ThisPath: /var/lib/openshift/************/php/tmp/phpSmk2Ew
ThisExt:
error echo: Uploaded file must end in .txt or .tab
Does this mean that OpenShift is renaming the file upon upload? How do I get the original filename and then check its suffix? More generally, is there a better way to check the file type?
$_FILES['uploadedfile']['tmp_name'] contains the name of a temporary file on the server (which can be moved with move_uploaded_file()). If you want to check the original name of the uploaded file on the client machine use $_FILES['uploadedfile']['name'].
That's not an Open Shift issue, it's the standard way of PHP.
For further details see http://php.net/manual/en/features.file-upload.post-method.php
For other ways to detect the file type see http://php.net/manual/en/ref.fileinfo.php

PHP - write to server folder denied

I have done chmod -R 777 on the root folder, but I'm still unable to successfully
upload (thus, write) to the uploaded folder!
Do I also have to change the php.ini file?
//$target_path = "http://localhost/photoServerProject/uploaded";
$target_path = "/photoServerProject/uploaded";
$fname = $_FILES["file"]["name"];
$upload_location = $target_path.'/'.$fname;
move_uploaded_file($_FILES["file"]["tmp_name"], $upload_location);
echo 'Moving file: ' . $fname . '</br></br>to: ' . $upload_location;
//echo "<img src=$upload_location>";
if(is_writeable($upload_location)){
echo '</br></br>Location <strong>is</strong> writeable ';
} else {
echo '</br></br>Location <strong>is NOT</strong> writeable ';
}
Output:
Moving file: camera.jpeg
to: /photoServerProject/uploaded/camera.jpeg
Location is NOT writeable
Try using
$targetPath= $_SERVER['DOCUMENT_ROOT'] . "photoServerProject/uploaded"
or
$targetPath= $_SERVER['DOCUMENT_ROOT'] . "/photoServerProject/uploaded"
I was confusing the difference between paths on my local drive vs server paths. My root folder (localhosts) for server paths is different than my local directory structure.
I was misunderstanding the difference between server and local disk directory structures. Namely, the root folders are different.
I'm surprised nobody brought up this issue.
Here's the solution:
<?php
$local_target = "~/webdev/photoServerProject/uploaded/";
$server_target = $_server['DOCUMENT_ROOT'] . "/photoServerProject/uploaded/";
$fname = $_FILES["file"]["name"];
$local_file_location = $local_target.$fname;
$server_file_location = $server_target.$fname;
move_uploaded_file($_FILES["file"]["tmp_name"], $local_file_location);
echo 'Moving file: ' . $fname . '</br></br>to local path: ' . $local_file_location;
echo '</br></br> But on the server it resides in : ' . $server_file_location;
echo '</br></br> See?';
echo "</br></br> <img src=$server_file_location>";
?>

Categories