Default How can I change create_function to anonymous function? - php

I am in the lengthy process of modernizing a lot of code on my website to make it php 8.x compliant. I have never really gotten the hang of user defined functions, so the following code was not created by me.
I am trying to change create_function, which has been removed as of php 8.0, to an anonymous function.
I removed the security lines as they were irrelevant.
Any hints as to how I should proceed?
Code:
print_r($_FILES)
##produces
$_FILES is Array ( [pix] => Array ( [name] => christmas every day.jpg [type] => image/jpeg [tmp_name] => /tmp/phpWPefKh [error] => 0 [size] => 91284 ) )
Here is the outdated code:
Code:
<?php
$end=substr($_FILES['pix']['name'],-3,3);
$end=strtolower($end);
if($end=="jpg"||$end=="peg"||$end=="gif"||$end=="png") {}
else {echo"<script type=\"text/javascript\">
window.location = \"http://www.animeviews.com\"
</script>";
exit;
}
function or_f($a, $b) {
return $a || $b;
}
function file_has_extension($fn, $ext) {
if(is_array($ext))
return array_reduce(array_map(create_function('$a', 'return file_has_extension(\'' . $fn . '\', $a);'), $ext), 'or_f', false);
else
return stripos($fn, '.' . strtolower($ext)) === strlen($fn) - strlen($ext) + 1;
}
$image_extensions = array(
'png',
'jpg',
'jpeg',
'gif'
);
if(!isset($_POST['Upload']) and !isset($_POST['Overwrite']))
{
include("picform.php");
} # endif
else
{
if($_FILES['pix']['tmp_name'] == "none")
{
echo "<b>File did not successfully upload. Check the
file size. File must be less than 500K.<br>";
include("picform.php");
exit();
}
if(file_has_extension($_FILES['pix']['name'], $image_extensions))
{
echo "<b>File is not a picture. Please try another
file.</b><br>";
include("picform.php");
exit();
}
else
{
$destination = $_FILES['pix']['name'];
$destination = strtolower($destination);
$temp_file = $_FILES['pix']['tmp_name'];
if (file_exists($destination) and $_POST['Overwrite']!="Overwrite") {
echo "The file $destination already exists.";exit();
}
#########
move_uploaded_file($temp_file,$destination);
echo "<p><b>The file has successfully uploaded:</b>
{$destination}
({$_FILES['pix']['size']})</p>";
$img="http://www.animeviews.com/images/$destination";
$img = $destination;
$width = "180px";
$height = "";
// Get new dimensions
list($width1, $height1) = getimagesize($img);
if ($width =="") {$j=$height/$height1; $width = $width1 * $j;}
if ($height=="") {$j=$width/$width1; $height = $height1 * $j;}
$new_width = $width;
$new_height = $height;
// Resample
$image_p = imagecreatetruecolor($width, $height);
$image = imagecreatefromjpeg($img);
imagecopyresampled($image_p, $image, 0, 0, 0, 0, $new_width, $new_height, $width1, $height1);
// Output
$img=preg_replace('/h.*\//','',$img);
$img=strtolower($img);
$dest="thumbs/$img";
imagejpeg($image_p,$dest);
}
}
?>

The purpose was to make sure that only images are uploaded, so create_function() or function() are not really needed. In fact, all I really needed was the following code snippet:
Code:
$end=substr($_FILES['pix']['type'], 0, 6);
$end=strtolower($end);
In short, the following code will check to see if the image being uploaded is an image. Not displayed is the code to be sure the user of the script is me. The script will overwrite the image if the same filename already exists and Overwrite was selected. A thumbnail is created and, lastly, a message is displayed saying that the file was successfully uploaded with the size.
Here is the full code:
Code:
<?php
$end=substr($_FILES['pix']['type'], 0, 6);
$end=strtolower($end);
if($end=="image/") {}
else {echo"<script type=\"text/javascript\">
window.location = \"http://www.animeviews.com/images/picform.php\"
</script>";
exit;
}
if(!isset($_POST['Upload']) and !isset($_POST['Overwrite']))
{
include("picform.php");
} # endif
else
{
if($_FILES['pix']['tmp_name'] == "none")
{
echo "<b>File did not successfully upload. Check the
file size. File must be less than 500K.<br>";
include("picform.php");
exit();
}
$destination = $_FILES['pix']['name'];
$destination = strtolower($destination);
$temp_file = $_FILES['pix']['tmp_name'];
if (file_exists($destination) and $_POST['Overwrite']!="Overwrite") {
echo "The file $destination already exists.";exit();
}
#########
move_uploaded_file($temp_file,$destination);
echo "<p><b>The file has successfully uploaded:</b>
{$destination}
({$_FILES['pix']['size']})</p>";
$img="http://www.animeviews.com/images/$destination";
$img = $destination;
$width = "180";
##$height = "";
// Get new dimensions
list($width1, $height1) = getimagesize($img);
if (!isset($width)) {$j=$height/$height1; $width = $width1 * $j;}
if (!isset($height)) {$j=$width/$width1; $height = $height1 * $j;}
$new_width = $width;
$new_height = $height;
// Resample
$image_p = imagecreatetruecolor($width, $height);
$image = imagecreatefromjpeg($img);
imagecopyresampled($image_p, $image, 0, 0, 0, 0, $new_width, $new_height, $width1, $height1);
// Output
$img=preg_replace('/h.*\//','',$img);
$img=strtolower($img);
$dest="thumbs/$img";
imagejpeg($image_p,$dest);
}

i'll try to describe the solution:
Legacy code: create_function('$a', 'return file_has_extension(\'' . $fn . '\', $a);')
Perfect code: function ($a) use ($fn) { return file_has_extension ($fn, $a); }
Explanation: in the first case, you can see the removed function named create_function, which creates a new closure (example of simple closue: function ($args) use ($extraArg - here is extra vars. which you need into the closure, 'use' - construction can be ummitted) { return ...$args }. Closure is equals type callable, you can read this documentation and see, that the first argument of previous function (it's array_map) will be the callable type, all you need pass the same type with the same behavior).
In the second case, you can see some strange construction like this use ($fn), it's necessary, because the closure|callable type has the own variable scope (more here).
More, about Closure and him scope here.
Rewritten file_has_extension function:
function file_has_extension($fn, $ext) {
if (is_array($ext)){
return array_reduce(
array_map(
function ($a) use ($fn) {
return file_has_extension($fn, $a);
},
$ext
),
function ($a, $b) {
return $a || $b;
},
false
);
}
return stripos($fn, '.' . strtolower($ext)) === strlen($fn) - strlen($ext) + 1;
}

Related

getimagesize () Read Error

I am using fuelphp framework. It uses getimagesize function (gd.php).
Function get called 3-4 times while converting image to different sizes. Some times it work or after getting called 2-3 times it throws "Read Error".
Site is hosted on Ubuntu machine with nginx server.
Thanks.
public function sizes($filename = null)
{
if (empty($filename) && !empty($this->image_fullpath))
{
$filename = $this->image_fullpath;
}
if ($filename == $this->image_fullpath && is_resource($this->image_data))
{
$width = imagesx($this->image_data);
$height = imagesy($this->image_data);
}
else if (is_resource($filename))
{
$width = imagesx($filename);
$height = imagesy($filename);
}
else
{
list($width, $height) = getimagesize($filename);
}
return (object) array('width' => $width, 'height' => $height);
}

How can I create custom thumbnails using php gd

i wanted to create a thumbnail with specific custom width & height. The function am using only create a thumbnail with a maximum set width/height.
How do i tweak the below function to give me a defined width/height e.g 50x50, 75x75, 100x100.
$original_photo = "photos/photo.extension";
$newcopy = "photos/thumbnails/photo.extension";
$copy_w = 50;
$copy_h = 50;
$extension = explode('.', 'photo.extension');
$extension = end($extension);
function create_thumbnail($original_photo, $newcopy, $copy_w, $copy_h, $extension) {
list($original_w, $original_h) = getimagesize($original_photo);
$scale_ratio = $original_w / $original_h;
if (($copy_w / $copy_h) > $scale_ratio) {
$copy_w = $copy_h * $scale_ratio;
} else {
$copy_h = $copy_w / $scale_ratio;
}
$img = '';
if ($extension == 'gif') {
$img = imagecreatefromgif($original_photo);
} elseif ($extension == 'png') {
$img = imagecreatefrompng($original_photo);
} else {
$img = imagecreatefromjpeg($original_photo);
}
$true_color = imagecreatetruecolor($copy_w, $copy_h);
imagecopyresampled($true_color, $img, 0, 0, 0, 0, $copy_w, $copy_h, $original_w, $original_h);
if (imagejpeg($true_color, $newcopy, 80) == true) {
return true;
} else {
return false;
}
}
Working with images in PHP/GD can be a pain. There are a lot of edge cases, particularly when transparent PNG/GIFs are manipulated.
If possible, I shamelessly recommend a library I wrote to handle things like this: SimpleImage 3.0
Using SimpleImage, you can achieve the desired effect with the following code:
// Load the image from image.jpg
$image = new \claviska\SimpleImage('image.jpg');
// Create a 50x50 thumbnail, convert to PNG, and write to thumbnail.png
$image->thumbnail(50, 50)->toFile('thumbnail.png', 'image/png');
See this page for more details on how the thumbnail method works and available arguments.

Compress and RESCALE uploaded image

I have a function that uploads files up to 8MB but now I also want to compress or at least rescale larger images, so my output image won't be any bigger than 100-200 KB and 1000x1000px resolution. How can I implement compress and rescale (proportional) in my function?
function uploadFile($file, $file_restrictions = '', $user_id, $sub_folder = '') {
global $path_app;
$new_file_name = generateRandomString(20);
if($sub_folder != '') {
if(!file_exists('media/'.$user_id.'/'.$sub_folder.'/')) {
mkdir('media/'.$user_id.'/'.$sub_folder, 0777);
}
$sub_folder = $sub_folder.'/';
}
else {
$sub_folder = '';
}
$uploadDir = 'media/'.$user_id.'/'.$sub_folder;
$uploadDirO = 'media/'.$user_id.'/'.$sub_folder;
$finalDir = $path_app.'/media/'.$user_id.'/'.$sub_folder;
$fileExt = explode(".", basename($file['name']));
$uploadExt = $fileExt[count($fileExt) - 1];
$uploadName = $new_file_name.'_cache.'.$uploadExt;
$uploadDir = $uploadDir.$uploadName;
$restriction_ok = true;
if(!empty($file_restrictions)) {
if(strpos($file_restrictions, $uploadExt) === false) {
$restriction_ok = false;
}
}
if($restriction_ok == false) {
return '';
}
else {
if(move_uploaded_file($file['tmp_name'], $uploadDir)) {
$image_info = getimagesize($uploadDir);
$image_width = $image_info[0];
$image_height = $image_info[1];
if($file['size'] > 8000000) {
unlink($uploadDir);
return '';
}
else {
$finalUploadName = $new_file_name.'.'.$uploadExt;
rename($uploadDirO.$uploadName, $uploadDirO.$finalUploadName);
return $finalDir.$finalUploadName;
}
}
else {
return '';
}
}
}
For the rescaling I use a function like this:
function dimensions($width,$height,$maxWidth,$maxHeight)
// given maximum dimensions this tries to fill that as best as possible
{
// get new sizes
if ($width > $maxWidth) {
$height = Round($maxWidth*$height/$width);
$width = $maxWidth;
}
if ($height > $maxHeight) {
$width = Round($maxHeight*$width/$height);
$height = $maxHeight;
}
// return array with new size
return array('width' => $width,'height' => $height);
}
The compression is done by a PHP function:
// set limits
$maxWidth = 1000;
$maxHeight = 1000;
// read source
$source = imagecreatefromjpeg($originalImageFile);
// get the possible dimensions of destination and extract
$dims = dimensions(imagesx($source),imagesy($source),$maxWidth,$maxHeight);
// prepare destination
$dest = imagecreatetruecolor($dims['width'],$dims['height']);
// copy in high-quality
imagecopyresampled($dest,$source,0,0,0,0,
$width,$height,imagesx($source),imagesy($source));
// save file
imagejpeg($dest,$destinationImageFile,85);
// clear both copies from memory
imagedestroy($source);
imagedestroy($dest);
You will have to supply $originalImageFile and $destinationImageFile. This stuff comes from a class I use, so I edited it quite a lot, but the basic functionality is there. I left out any error checking, so you still need to add that. Note that the 85 in imagejpeg() denotes the amount of compression.
you can use a simple one line solution through imagemagic library the command will like this
$image="path to image";
$res="option to resize"; i.e 25% small , 50% small or anything else
exec("convert ".$image." -resize ".$res." ".$image);
with this you can rotate resize and many other image customization
Take a look on imagecopyresampled(), There is also a example that how to implement it, For compression take a look on imagejpeg() the third parameter helps to set quality of the image, 100 means (best quality, biggest file) and if you skip the last option then default quality is 75 which is good and compress it.

Uploading Image from device to server, how to return final url of img as string

So I have it set up to upload images via Phonegap native apis from devices images/camera with random numbers attached to the image name. I'm trying to figure out how to access the final url of the image location on the server so that I can utilize that url of the image when making a Facebook post since they require external uploaded images.
Code:
.php
<?php
$dir = "upload";
$randomImg = rand(1, 9999)."image".rand(1, 999999).".jpg";
if ($_FILES) {
print_r($_FILES);
mkdir ($dir, 0777, true);
move_uploaded_file($_FILES["file"]["tmp_name"],$dir."/".$randomImg);
}
else if (isset($_GET['image'])) {
$image = $dir."/".$_GET['image'];
header('Content-type: image/jpeg');
list($width, $height) = getimagesize($image);
$newWidth = 120.0;
$size = $newWidth / $width;
$newHeight = $height * $size;
$resizedImage = imagecreatetruecolor($newWidth, $newHeight);
$image = imagecreatefromjpeg($image);
imagecopyresampled($resizedImage, $image, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);
imagejpeg($resizedImage, null, 80);
}
else {
$images = scandir($dir);
$ignore = Array(".", "..");
$baseURI = "http://".$_SERVER['SERVER_NAME'].':'.$_SERVER['SERVER_PORT'].$_SERVER['REQUEST_URI'];
if ($images) {
foreach($images as $curimg){
if (!in_array($curimg, $ignore)) {
echo "Image: ".$curimg."<br>";
echo "<img src='".$baseURI."?image=".$curimg."&rnd=".uniqid()."'><br>";
}
}
}
else {
echo "We apologize, but there are no images found on our server at this time.";
}
}
?>
.html
<section>
<input value="Upload Photo" id="uploadBtn" type="button" onclick="uploadImg();" />
</section>
.js
function uploadImg() {
var img = document.getElementById('camImg');
var imageURI = img.src;
if (!imageURI || (img.style.display === "none")) {
$('#status').html("Snap a photo or select one from your gallery by clicking the 'Attach Photo...' button").css('color', 'red');
return;
}
paramount = "http://www.param0unt.com/app/upload.php";
if (paramount) {
var opts = new FileUploadOptions();
opts.fileKey = "file";
opts.fileName = imageURI.substr(imageURI.lastIndexOf('/') + 1);
opts.mimeType = "image/jpeg";
opts.chunkedMode = false;
var media = new FileTransfer();
media.upload(imageURI, paramount, function(r) {
$('#status').html("Photo successfully stored on our server! (<font color='red'>NOTE:</font> This is alpha version, you will be able to utilize these photos via facebook group ad posts in an upcoming beta release!)").css('color', 'green');
}, function(error) {
$('#status').html("Photo Upload Failed, please try again later.").css('color', 'red');
//console.log(error.code);
}, opts);
}
}
After you have uploaded the file with move_uploaded_file, generate the URL and echo it back as a JSON-encoded response:
$url = $baseURI . "?image=" . $randomImg; // http://example.com/app/upload.php?image=1234image5678.jpg
echo json_encode(array("url" => $url));
exit;
Then in your success callback JS function, parse the response:
var data = JSON.parse(r);
console.log(data.url); // http://example.com/app/upload.php?image=1234image5678.jpg

image upload problem

I wrote a function to resize and upload images...it works, but only for one image. So if I call the function three times, I end up with 3 copies of the last image.....
function uploadImage($name,$width,$height,$size,$path='content/user_avatars/')
{
//===================================================
//Handle image upload
$upload_error=0;
//Picture
$img = $_FILES[$name]['name'];
if($img)
{
$file = stripslashes($_FILES[$name]['name']);
$ext = strtolower(getExt($file));
if($ext!='jpg' && $ext!='jpeg' && $ext!='png' && $ext!='gif')
{
$error_msg = "Unknown extension";
$upload_error = 1;
return array($upload_error,$error_msg);
}
if(filesize($_FILES[$name]['tmp_name'])>$size*1024)
{
$error_msg = "Max file size of ".($size*1024)."kb exceeded";
$upload_error = 2;
return array($upload_error,$error_msg);
}
$newFile = time().'.'.$ext;
resizeImg($_FILES[$name]['tmp_name'],$ext,$width,$height);
$store = copy($_FILES[$name]['tmp_name'],$path.$newFile);
if(!$store)
{
$error_msg = "Uploading failed";
$upload_error = 3;
return array($upload_error,$error_msg);
}
else
{
return array($upload_error,$newFile);
}
}
}
//=========================================================================================
//Helper Functions
function getExt($str)
{
$i = strpos($str,".");
if(!$i)
{
return "";
}
$l = strlen($str)-$i;
$ext = substr($str,$i+1,$l);
return $ext;
}
function resizeImg($file,$ext,$width,$height)
{
list($aw,$ah) = getimagesize($file);
$scaleX = $aw/$width;
$scaleY = $ah/$height;
if($scaleX>$scaleY)
{
$nw = round($aw*(1/$scaleX));
$nh = round($ah*(1/$scaleX));
}
else
{
$nw = round($aw*(1/$scaleY));
$nh = round($ah*(1/$scaleY));
}
$new_image = imagecreatetruecolor($nw,$nh);
imagefill($new_image,0,0,imagecolorallocatealpha($new_image,255,255,255,127));
if($ext=='jpg'||$ext=='jpeg')
{
$src_image = imagecreatefromjpeg($file);
}
else if($ext=='gif')
{
$src_image = imagecreatefromgif($file);
}
else if($ext=='png')
{
$src_image = imagecreatefrompng($file);
}
imagecopyresampled($new_image,$src_image,0,0,0,0,$nw,$nh,$aw,$ah);
if($ext=='jpg'||$ext=='jpeg')
{
imagejpeg($new_image,$file,100);
}
else if($ext=='gif')
{
imagegif($new_image,$file);
}
else if($ext=='png')
{
imagepng($new_image,$file,9);
}
imagedestroy($src_image);
imagedestroy($new_image);
}
I have a form with two upload fields, 'face_pic' and 'body_pic', and I want to upload these two to the server and resize them before storing. Any ideas?
You use the current time to determine the resulting name of the file. The function executes so fast, that time() yields the same result for both images.
Use some other means to disambiguate the resulting name of the file. Best choice would be to pass the resulting name as a parameter. That way, the environment can determine how the file is named. Candidates are primary key of the meta information (in case they are stored in the database), original file name, universally unique identifier.
In any case, check whether the resulting name is a legal filename on your platform and that you do not accidentally overwrite files.
Also consider using move_uploaded_file to move the file from the temporary location to the destination. That function does some security checking.
md5(microtime())
Try naming it like this.
Or try something like this...
function slikeAvatar($slika,$id = 0){
copy($slika, "avatari/{$id}l.jpg");
$gfx = new Thumbnail($slika, 200);
$gfx->save("avatari/{$id}.jpg");
unset($gfx);
$gfx = new Thumbnail($slika, 75);
$gfx->save("avatari/{$id}s.jpg");
unset($gfx);
slikeCrop("avatari/{$id}s.jpg","avatari/{$id}s.jpg");
}
slike = images

Categories