I have a very weird problem with php and I can't find any explanation for it.
I want to add this line of code to grab extension from the sent file:
$extension = array_pop( explode( "." , $_FILES["myFiles"]["name"][$key]);
but if i do so php doens't send a respond although the file is saved successfully. If I simply delete this line and hardcode ".jpg" instead $extension it sends the response as expected.
<?php
$response = array();
if (isset($_FILES)) {
foreach ($_FILES["myFiles"]["tmp_name"] as $key => $value) {
$user = $_POST["user"];
// when i add the line below it deosn't send the response!
$extension = array_pop( explode( "." , $_FILES["myFiles"]["name"][$key]) );
move_uploaded_file($value, "uploads/$user.$extension");
};
$response["msg"] = "image has been uploaded";
} else {
$response["msg"] = "selcect an image";
}
echo json_encode($response);
array_pop takes argument by reference. You can't provide argument directly from another function to array_pop.
Instead in your case you should do this:
$parts = explode("." , $_FILES["myFiles"]["name"][$key]);
$extension = array_pop($parts);
But! You should NEVER trust client's data, even if it's just a file extension. It is better to check extension itself (is it jpg, png, svg, gif), also check if the file is really an image, check size of that image, etc...
Related
I am trying to get list of all those files whose extension is jpeg,jpg or png and title contains '100x100' text.
I can easily get the list of files filtering by their extension, that's working fine but when I add a condition into it && str_contains($value,'100x100') then page is not working and gives HTTP ERROR 500
function:
function scan_files(){
$upload_dir = wp_upload_dir();
$folder = $upload_dir['basedir'];
$files = list_files( $folder );
foreach($files as $value){
if(pathinfo($value, PATHINFO_EXTENSION)=='jpeg'||pathinfo($value, PATHINFO_EXTENSION)=='jpg'||pathinfo($value, PATHINFO_EXTENSION)=='png' && str_contains($value,'100x100')){
$filtered_files[] = $value;
}
}
echo "<pre>";
print_r($filtered_files);
}
Can anyone help?
UPDATE
According #luk2302 's comment I have corrected the ) issue and page is working fine but values are not getting filtered, also according to #CBroe 's comment, I am using php7 so I replaced str_contains with strpos but still it's not giving expected results.
New Code:
function scan_files(){
$upload_dir = wp_upload_dir();
$folder = $upload_dir['basedir'];
$files = list_files( $folder );
foreach($files as $value){
if(pathinfo($value, PATHINFO_EXTENSION)=='jpeg'||pathinfo($value, PATHINFO_EXTENSION)=='jpg'||pathinfo($value, PATHINFO_EXTENSION)=='png' && strpos($value,'100x100')!==false){
$filtered_files[] = $value;
}
}
echo "<pre>";
print_r($filtered_files);
}
Change this line:
if(pathinfo($value, PATHINFO_EXTENSION)=='jpeg'||pathinfo($value, PATHINFO_EXTENSION)=='jpg'||pathinfo($value, PATHINFO_EXTENSION)=='png' && strpos($value,'100x100')!==false){
To:
if((pathinfo($value, PATHINFO_EXTENSION)=='jpeg'||pathinfo($value, PATHINFO_EXTENSION)=='jpg'||pathinfo($value, PATHINFO_EXTENSION)=='png') && strpos($value,'100x100')!==false){
Notice the extra parentheses around your pathinfo statements. You want to check if any of the extensions are true AND the path contains your key value. Your original code would only filter on filename if the extension was png.
Trying to upload file to my test api. For testing I tried to check if input has file and it returns true. The problem is when the code tries to move that file. Search google show almost the same code that I have;
if (Input::hasFile('attachments')) {
$path = base_path().'/assets';
$files = Input::file('attachments');
$data = [];
foreach ($files as $file) {
$data[] = $file->getClientOriginalExtension();
$uuid = Uuid::uuid1();
$extension = $file->getClientOriginalExtension();
$filename = $uuid.'.'.$extension;
$file->move($path, $filename);
}
return Response::json($data);
} else {
return 'no file';
}
Doing a post request using Paw multipart give this result on json
Still can't figure this out. Any help will be much appreciated. Thank you so much guys in advance.
Ok; so something as simple as this [] gave me a hard time figuring things out. All I did is add []; instead of just attachments I did attachments[] as post request name and in my controller I retain the Input::file('attachments')
Thank you guys for your guidance and help. Figured things out the hard and tired way.
I don't know why you are trying to iterate but there is no reason to and $files is a single uploaded file.
Just remove the loop since there is nothing to iterate.
if (Input::hasFile('attachments')) {
$path = base_path().'/assets';
$file = Input::file('attachments');
$uuid = Uuid::uuid1();
$extension = $file->getClientOriginalExtension();
$filename = $uuid.'.'.$extension;
$file->move($path, $filename);
return Response::json($extension);
} else {
return 'no file';
}
If you wanted to have multiple files you would need to have the input setup to be named as an array, attachments[]. You are sending attachments which is always a single value. If you sent an array then there would potentially be something for you to iterate through.
I have a file picviwer.php that loads a pic as following:
<img src="http://www.example.com/loadimage?uid=$id&view=pic" id="ppic" />
It sends a GET request to a another file loadimage.php with the id of the photo to be loaded.
Below is the code for loadimage.php
if(isset($_GET['uid'])){
$uid = $_GET['uid'];
$remoteImage = "http://www.example.com/user-pics/".$uid.".png";
$img = file_get_contents($remoteImage);
header('Content-Type: image/x-png'); //or whatever
readfile($remoteImage);
}
Right now the above code deals only for png image and I wish to extend for images of all types(.jpg,.gif etc.). For this I want to get the extension of the image and then send headers accordingly. Also append the correct extension with the filename(uid).How can I do that?
i hope it will help you . it would be little long but surly will work and can add more extension in else if condtion .
if(file_exists("http://www.example.com/user-pics/".$uid.".png")) {
$remoteImage = "http://www.example.com/user-pics/".$uid.".png";
}elseif( file_exists("http://www.example.com/user-pics/".$uid.".jpg") ){
$remoteImage = "http://www.example.com/user-pics/".$uid.".jpg";
}
and so on
I would recommend not accessing the files via the full domain name but by the path they are on your server. This would eliminate the server load it takes to form a internal HTTP request to check the file existence and read the content.
You could find the exiting extensions as follows:
if(isset($_GET['uid'])){
$uid = $_GET['uid'];
$imagesPath = '/path/to/images/'; //REPLACE with the correct server path
$existingImage = '';
foreach (glob($imagesPath . $uid . ".*") as $filename) {
// this matches all files with name $uid and an existing extension. If you have preferred extensions handle them here.
$existingImage = $filename;
break; // We only need one if we have no extension preference
}
if ('' === $existingImage) {
// No images are found that have the required filename. Handle this exception here
}
$finfo = finfo_open(FILEINFO_MIME_TYPE); // return mime type ala mimetype
$imgMimeType = finfo_file($finfo, $existingImage);
finfo_close($finfo);
header('Content-Type: ' . $imgMimeType);
readfile($existingImage );
}
You can grab the extension for a file using:
$extension = pathinfo($imagePath, PATHINFO_EXTENSION);
To get the correct mime-type for the header use exif_imagetype() to get the imagetype which can be converted to the correct mime-type.
(provided you will only use images).
$imageType = exif_imagetype($imagePath);
$headerString = 'Content-Type:'. image_type_to_mime_type ($imageType);
header($headerString);
I am not real good at reading the code for uploading images via php/ajax so i am hoping a php guru can help me out. I am trying to take the image file name and if it has spaces in it then replace those spaces with an underscore "_"
The php code for uploading is this:
$file_name = ( isset($_REQUEST['ax-file-name']) && !empty($_REQUEST['ax-file-name']) )?$_REQUEST['ax-file-name']:'';
$currByte = isset($_REQUEST['ax-start-byte'])?$_REQUEST['ax-start-byte']:0;
if($is_ajax)//Ajax Upload, FormData Upload and FF3.6 php:/input upload
{
//we get the path only for the first chunk
$full_path = ($currByte==0) ? checkFileExits($file_name, $upload_path):$upload_path.$file_name;
//Just optional, avoid to write on exisiting file, but in theory filename should be unique from the checkFileExits function
$flag = ($currByte==0) ? 0:FILE_APPEND;
//formData post files just normal upload in $_FILES, older ajax upload post it in input
$post_bytes = isset($_FILES['Filedata'])? file_get_contents($_FILES['Filedata']['tmp_name']):file_get_contents('php://input');
//some rare times (on very very fast connection), file_put_contents will be unable to write on the file, so we try until it writes
while(#file_put_contents($full_path, $post_bytes, $flag) === false)
{
usleep(50);
}
//delete the temporany chunk
if(isset($_FILES['Filedata']))
{
#unlink($_FILES['Filedata']['tmp_name']);
}
//if it is not the last chunk just return success chunk upload
if($isLast!='true')
{
echo json_encode(array('name'=>basename($full_path), 'size'=>$full_size, 'status'=>1, 'info'=>'Chunk uploaded'));
}
}
else //Normal html and flash upload
{
$isLast = 'true';//we cannot upload by chunks here so assume it is the last single chunk
$full_path = checkFileExits($file_name, $upload_path);
$result = move_uploaded_file(str_replace(" ", "_",$_FILES['Filedata']['tmp_name']), $full_path);//make the upload
if(!$result) //if any error return the error
{
echo json_encode( array('name'=>basename($full_path), 'size'=>$full_size, 'status'=>-1, 'info'=>'File move error') );
return false;
}
}
I've already tried the following (with str_replace(" ", "_", $nameoffile):
$post_bytes = isset($_FILES['Filedata'])? file_get_contents(str_replace(" ", "_",$_FILES['Filedata']['tmp_name'])):file_get_contents('php://input');
That seems to do nothing to rename it. So where am i missing it at?
The problem in your code is , you are trying to rename the temporary name of image file not the actual name
move_uploaded_file(str_replace(" ", "_",$_FILES['Filedata']['tmp_name']), $full_path);//make the upload
So you have to remove the str_replace from temporary name and append this to actual name like this.
move_uploaded_file($_FILES['Filedata']['tmp_name'], str_replace(" ", "_",$full_path));//make the upload
Hope it clarifies your doubt.
I've run into a typical problem here. Till now i was doing
strstr($filename,".");
$filename is the file i got from $_FILE i.e uploaded file.It was running fine until i hit a filename of the type i mentioned.
Even doing
pathinfo($filename);
gives me
.gz
I need to see whether it is EXACTLY
.tar.gz
Technically, pathinfo is correct: the one and only extension for that file is .gz. The fact that it has .tar in the name is as coincidental as the fact that it has 5.0.1 in it.
That doesn't make your interest in checking for .tar.gz files invalid, but it does raise the question: what specifically do you want to find?
The most direct solution to your specific question is: first look for the extension (via pathinfo or the strpos function) and then if it happens to be .gz look for the "extension" in the remaining filename (via the same technique).
$parts = pathinfo($filename);
$extension = $parts['extension'];
if ($extension == '.gz') {
$parts = pathinfo($parts['filename']);
$extension = $parts['extension'] . $extension;
}
The most simple way would be to check for the last 7 characters of the filename - this ensures that every file ends with .tar.gz:
if (substr($filename, -7) == '.tar.gz') {
// continue
}
And if you needed to parse 'this.is.a.very.long.file.name.with.lots.of.full.stops' then what part of that is the file extension? Relying on a particular part of a filename to convey semantic, machine readable information about the contents of the file is, at best dangerous.
It's not clear what the problem you are trying is - why do you need to know what the extension is?
C.
I just posted the following enhanced version of pathinfo() in comments over on PHP.net. This version groups all of the parts of the file extension in as the extension (e.g. "tar.gz" instead of just "gz"), leaving the rest as the filename:
<?php
function pathinfo_enhanced($file_path) {
$core_path_info = pathinfo($file_path);
$filename = $core_path_info['filename'];
if (isset($core_path_info['extension'])) {
$extension = $core_path_info['extension'];
} else {
$extension = '';
}
$extension_parts = array();
while (!empty($extension)) {
array_unshift($extension_parts, $extension);
$remaining_path_info = pathinfo($filename);
$filename = $remaining_path_info['filename'];
if (isset($remaining_path_info['extension'])) {
$extension = $remaining_path_info['extension'];
} else {
$extension = '';
}
}
$revised_path_info = array(
'filename' => $filename,
'extension' => implode('.', $extension_parts),
);
return array_merge($core_path_info, $revised_path_info);
}
Here are some examples you can run to show how it handles the different cases:
// Directory; two extensions
$path = '/www/htdocs/inc/file.tar.gz';
$info = pathinfo_enhanced($path);
echo "$path\n";
print_r($info);
echo "\n";
// Directory; one extension
$path = '/www/htdocs/inc/file.tgz';
$info = pathinfo_enhanced($path);
echo "$path\n";
print_r($info);
echo "\n";
// Directory; no extension
$path = '/www/htdocs/inc/lib';
$info = pathinfo_enhanced($path);
echo "$path\n";
print_r($info);
echo "\n";
// No directory; one extension
$path = 'test.php';
$info = pathinfo_enhanced($path);
echo "$path\n";
print_r($info);
echo "\n";
// No directory; dot file
$path = '.example';
$info = pathinfo_enhanced($path);
echo "$path\n";
print_r($info);
echo "\n";
// Directory only
$path = '/www/htdocs/inc/';
$info = pathinfo_enhanced($path);
echo "$path\n";
print_r($info);
echo "\n";
THIS is the answer:
strstr(pathinfo('asdasd/qweqwe/asdasd.tar.gz')['basename'], '.');
will return you '.tar.gz'