I am using a PHP function to add my logo as the watermark on images uploaded on my website. But I don't know why my watermark function is not working for png files. however, it works for jpeg files perfectly. this is my PHP function.
function watermark($img) {
global $wm_file, $wm_right, $wm_bottom;
// image values pulled from config.inc.php
$logo = './images/' . $wm_file; // path to the watermark.png
$sp = $wm_right; // spacing from right side
$sq = $wm_bottom; // spacing from bottom
$size = getImageSize($img);
$sizel = getImageSize($logo);
$imgA = imageCreateFromJpeg($img);
imageAlphaBlending($imgA, TRUE);
if($sizel[0] > $size[0] || $sizel[1] > $size[1])
{
// logo size > img size
$sizelo[0] = $sizel[0];
$sizelo[1] = $sizel[1];
$sizel[0] = ($sizel[0]/2);
$sizel[1] = ($sizel[1]/2);
}
else
{
$sizelo[0] = $sizel[0];
$sizelo[1] = $sizel[1];
}
$imgBa = imageCreateFromPng($logo);
$imgB = imageCreateTrueColor($sizel[0], $sizel[1]);
imageAlphaBlending($imgB, TRUE);
imageCopyResampled($imgB, $imgBa, 0, 0, 0, 0, $sizel[0], $sizel[1], $sizelo[0], $sizelo[1]);
imageColorTransparent($imgB, ImageColorAllocate($imgB, 0, 0, 0));
$perc = 100;
imageCopymerge($imgA, $imgB, ($size[0]-$sizel[0]-$sp), ($size[1]-$sizel[1]-$sq), 0, 0, $sizel[0], $sizel[1], $perc);
unlink($img);
if(imageJpeg($imgA, $img, 100))
{
imageDestroy($imgB);
imageDestroy($imgA);
return true;
}
chmod($img, 0777);
}
The problem I see is that you are using imageCreateFromJpeg() as the way to generate the resource for your $img that you are passing to the function.
If you pass a jpeg through the function it will work. If you pass a png it will not.
I recommend using imagecreatefromstring() to create all your resources as it is not dependent on the file type. Like so:
$source = imagecreatefromstring(file_get_contents($filePath));
Another benefit of this is that it will return false if the function fails to create a resource from the file path that you supplied meaning that the file is not an image file.
Now that you have a resource to use for the rest of your code, imageJpeg() will save the resource as a jpeg back to the file path.
Hope that helps.
One other side note. If you intend on using bmp images, the GD library does not have a built in function for bmps. However on PHP.net, someone did write a createimagefromBMP() that works really well. Also I think that on the latest version of PHP the GD library does now actually have a createimagefromBMP() function.
I also see that you are using unlink() to delete the image from your directory. This is not necessary for two reasons. The imageJpeg() will just overwrite the original. Also, if for some reason your script fails it may delete the image prematurely and you will loose the image without the new one being written.
Please be careful when using chmod(), always make sure that you set permissions back to the original permissions when you are done.
chmod($img, 777); //Give broad permissions.
//Do something.
chmod($img, 600(or whatever they were)); //Reset permission back to where they were before you changed them.
Related
This is currently what I have. When I include it in my index.php and then call the function on pageload, I get a blank page. So something is wrong here, but I don't know what. I feel like I'm really close though. I just want to create thumbnails of images in a directory, and then show them in HTML as a list of images you can click that trigger lightboxes.
I'm still really shaky in PHP. I'm trying to wrap my head around editing images in a directory.
<?php
function buildThumbGallery(){
$h = opendir('/Recent_Additions/'); //Open the current directory
while (false !== ($curDir = readdir($h))) {
if (!file_exists('/Recent_Additions/thumbs/')) {
$thumbDir = mkdir('/Recent_Additions/thumbs/', 0777, true);
}else{
$thumbDir = '/Recent_Additions/thumbs/';
}
$width = 200;
$height = 200;
foreach ($curDir as $image) {
$filePath = $curDir."/".$image;
$genThumbImg = $image->scaleImage($width, $height, true);
$newThumb = imagejpeg($genThumbImg, $thumbDir, 100);
echo '<li> <a class="fancybox" data-fancybox-group="'.basename($curDir).'" href="'.$filePath.'" title="'.basename($curDir)." ".strpbrk(basename($filePath, ".jpg"), '-').'"><img src="'.$newThumb.'"/>'.basename($curDir).'</a>';
imagedestroy($newThumb);
}echo '</li>';
}
?>
You are doing several things wrong:
You're not closing the while loop.
Readdir already loops through a directory, your foreach is not doing anything.
You are missing quotes in your echo.
You are calling the method scaleImage on a string, I think you meant to call the function imagescale.
You're missing and misunderstanding a lot of stuff, take a look at how to create a thumbnail here: https://stackoverflow.com/a/11376379/4193448
Also see if you can enable PHP errors, getting a blank page while your code is full of errors is not really helping is it?
::EDIT::
With help from #swordbeta, I got my script working properly. Here is the code for future reference:
<?php
function buildThumbGallery(){
$curDir = "./Recent_Additions/";
$thumbsPath = $curDir."thumbs/";
if (!file_exists($thumbsPath)) {
mkdir($thumbsPath, 0777, true);
}
foreach(scandir($curDir) as $image){
if ($image === '.' || $image === '..' || $image === 'thumbs') continue;
if(!file_exists($thumbsPath.basename($image, ".jpg")."_thumb.jpg")){
// Max vert or horiz resolution
$maxsize=200;
// create new Imagick object
$thumb = new Imagick($curDir.$image); //'input_image_filename_and_location'
$thumb->setImageFormat('jpg');
// Resizes to whichever is larger, width or height
if($thumb->getImageHeight() <= $thumb->getImageWidth()){
// Resize image using the lanczos resampling algorithm based on width
$thumb->resizeImage($maxsize,0,Imagick::FILTER_LANCZOS,1);
}else{
// Resize image using the lanczos resampling algorithm based on height
$thumb->resizeImage(0,$maxsize,Imagick::FILTER_LANCZOS,1);
}
// Set to use jpeg compression
$thumb->setImageCompression(Imagick::COMPRESSION_JPEG);
$thumb->setImageCompressionQuality(100);
// Strip out unneeded meta data
$thumb->stripImage();
// Writes resultant image to output directory
$thumb->writeImage($thumbsPath.basename($image, ".jpg")."_thumb.jpg"); //'output_image_filename_and_location'
// Destroys Imagick object, freeing allocated resources in the process
$thumb->destroy();
}else{
echo '<a class="fancybox" data-fancybox-group="'.basename($curDir).'" href="'.$curDir.basename($image, "_thumb.jpg").'" title="Recent Addition - '.basename($image, ".jpg").'"><img src="'.$thumbsPath.basename($image, ".jpg")."_thumb.jpg".'"/></a>';
echo '<figcaption>'.basename($image, ".jpg").'</figcaption>' . "<br/>";
}
}
}
?>
::Original Post::
Ok, after going back and doing some more research and suggestions from #swordbeta, i've got something that works. My only issue now is I can't get the images to show in my index.php. I'll style the output in CSS later, right now I just want to see the thumbnails, and then later build them into lightbox href links:
<?php
function buildThumbGallery(){
$curDir = "./Recent_Additions/";
$thumbsPath = $curDir."/thumbs/";
if (!file_exists($thumbsPath)) {
mkdir($thumbsPath, 0777, true);
}
$width = 200;
foreach(scandir($curDir) as $image){
if ($image === '.' || $image === '..') continue;
if(file_exists($thumbsPath.basename($image)."_thumb.jpg")){
continue;
}else{
// Max vert or horiz resolution
$maxsize=200;
// create new Imagick object
$thumb = new Imagick($curDir.$image); //'input_image_filename_and_location'
// Resizes to whichever is larger, width or height
if($thumb->getImageHeight() <= $thumb->getImageWidth()){
// Resize image using the lanczos resampling algorithm based on width
$thumb->resizeImage($maxsize,0,Imagick::FILTER_LANCZOS,1);
}else{
// Resize image using the lanczos resampling algorithm based on height
$thumb->resizeImage(0,$maxsize,Imagick::FILTER_LANCZOS,1);
}
// Set to use jpeg compression
$thumb->setImageCompression(Imagick::COMPRESSION_JPEG);
$thumb->setImageCompressionQuality(100);
// Strip out unneeded meta data
$thumb->stripImage();
// Writes resultant image to output directory
$thumb->writeImage($thumbsPath.basename($image)."_thumb.jpg"); //'output_image_filename_and_location'
// Destroys Imagick object, freeing allocated resources in the process
$thumb->destroy();
}
} echo '<img src="'.$thumbsPath.basename($image)."_thumb.jpg".'" />' . "<br/>";
}
?>
At the moment, the output from the echo isn't showing anything, but the rest of the script is working properly (i.e. generating thumbnail images in a thumbs directory).
I'm guessing i'm not formatting my echo properly. This script is called in my index.php as <?php buildThumbGallery(); ?> inside a styled <div> tag.
I'm trying to read a directory of .jpg files from a folder ./gallery/, make them a bit smaller, and then save them back to ./gallery/_thumbs/.
Everything seems to work up until I try to use the imagecopyresampled() to actually do the resizing. The PHP man says it should return a bool on success/failure, but I'm able to get anything and hence don't know what I'm doing wrong.
I'm assuming that if I get a valid result from imagecopyresampled() that the imagejpeg() will work okay the way I have it?
for($i=0;$files_in_dir[$i]!=null;$i++)
{
if (!($files_in_dir[$i]=="."||$files_in_dir[$i]==".."||$files_in_dir[$i]=="_thumb"))
{
$my_images['image_name']=$files_in_dir[$i];
$my_images['path_to_current']=$directory.$my_images['image_name'];
$my_images['path_to_finished_thumb']=$directory.$sub_directory.$prefix.$my_images['image_name'];
$my_images['image_handler']=imagecreatefromjpeg($my_images['path_to_current']);
$imagesize = getimagesize($my_images['path_to_current']);
$my_images['width']=$imagesize[0];
$my_images['height']=$imagesize[1];
$my_images['ratio']=$my_images['height']/$my_images['width'];
$my_height = round($my_width / $ratio);
echo "<pre>";
var_dump($my_images);
$newImage = imagecreatetruecolor($my_width,$my_height);
$success = imagecopyresampled($newImage,$my_images['image_handler'],0,0,0,0,$my_width,$my_height,$my_images['width'],$my_images['height']);
echo "my success was: ",$success,"<br />";
imagejpeg($newImage,$my_images['path_to_finished_thumb'],80);
imagedestroy($my_images['image_handler']);
imagedestroy($newImage);
echo "</pre>";
}
}
?>
There are a couple things to come to mind.
First, check to make sure PHP is able to write to the files and directories in question.
Make sure you're seeing all errors/warnings so you know when something fails.
From your report it certainly sounds like your copy of PHP has the GD extension installed, but do make sure before you assume that extension-based functions like imagejpeg() are available. You can use a page containing <?php phpinfo(); to determine this yourself, or you can do it programmatically using function_exists().
I've taken the liberty of streamlining your script to make it easier to catch possible bugs (fewer lines = fewer possible mistakes):
<?php
// Make sure we see processing errors during development/testing.
error_reporting(E_ALL);
ini_set('display_errors', true);
// Set up operating parameters.
$filePattern = 'gallery/*.[jJ][pP][gG]';
$thumbPattern = 'thumbs/%s';
$targetWidth = 200;
$targetQuality = 80;
// Create the output dir, if it doesn't already exist. This will fail
// if PHP does not have write access to the local folder.
$thumbDir = sprintf($thumbPattern, '');
if (!is_dir($thumbDir)) {
mkdir($thumbDir);
}
// Abort if GD is not installed.
if (!function_exists('imagejpeg')) {
die('PHP does not have the GD extension installed. Aborting.');
}
// Abort if the output directory is not writable.
if (!is_writable($thumbDir)) {
die('The output directory is not writable by PHP. Check permissions. Aborting.');
}
// Loop over all found jpg files.
foreach (new GlobIterator($filePattern) as $f) {
// var_dump($f->getRealpath()); // Debugging the path name.
// Skip regenerating cached thumbs for performance.
$thumbPath = sprintf($thumbPattern, $f->getFilename());
if (file_exists($thumbPath)) {
continue;
}
// Determine thumbnail output size.
list($w, $h) = getimagesize($f->getRealpath());
$ratio = $h / $w;
$targetHeight = round($targetWidth * $ratio);
// Generate the thumbnail from the original.
$jpg = imagecreatefromjpeg($f->getRealpath());
$thumb = imagecreatetruecolor($targetWidth, $targetHeight);
$success = imagecopyresampled(
$thumb,
$jpg,
0, 0, 0, 0,
$targetWidth, $targetHeight, $w, $h
);
imagejpeg($thumb, $thumbPath, $targetQuality);
}
(Gist version here.)
One thing I caught during this process was that the logic for determining the thumbnail ratio was reversed. It needs to be $targetWidth * $ratio (instead of $targetWidth / $ratio).
This version of the script doesn't do the same naming manipulation-- it just creates a new thumbs/ folder wherever the script lives and saves the thumbnail versions from gallery/ into it.
I'm writing a PHP-based image viewer, and I've come across an odd issue. When I click an image to view it, the code says that it should show a resized version of the picture, which it has created and saved to the hard drive (so it doesn't need to remake the image more than once). However, it just shows a broken image and outputs an error complaining that the file it's looking for doesn't exist. If I refresh the page, the file does exist, and loads fine. What is going on here? I was under the impression that PHP was single-threaded
Below is the entirety of image-view.php (I have since deleted this code, as I made it for work, and it's not relevant to the problem I had)
Here is the resize_image() function from functions.php
//Return the path to a new or already existing resized version of the image you are looking for.
//I repeat: THIS FUNCTION RETURNS A PATH. IT DOES NOT RETURN AN ACTUAL IMAGE.
function resize_image($img, $imgPath, $width) {
//error_log("!!!Calling resize_image({$img},{$imgName},{$width},{$imgDir})!!!");
//Put the image in the .cache subdirectory.
$imgName = end(explode("/",$imgPath));
$imgDir = str_replace($imgName,"",$imgPath);
$pathToThumbs = $imgDir . "/.cache/";
$thumbWidth = $width;
$thumbHeight = floor(imagesy($img) * ($width / imagesx($img)));
$thumbName = get_resized_image_name($thumbWidth, $thumbHeight, $imgName);
$resizedPath = "{$pathToThumbs}{$thumbName}";
//Don't make a new image if it already exists.
if (file_exists($pathToThumbs)) {
if (file_exists($resizedPath)) {
error_log("Resized image {$resizedPath} already exists. Exiting.");
return $resizedPath;
}
}
else {
error_log("Cache folder does not exist. Creating.");
$old_umask = umask(0);
mkdir($pathToThumbs, 0777);
umask($old_umask);
}
error_log("Resized image {$resizedPath} does not exist. Creating.");
$thumb = imagecreatetruecolor($thumbWidth, $thumbHeight);
//This is the magic line right here. Create the thumbnail.
imagecopyresized($thumb, $img, 0, 0, 0, 0, $thumbWidth, $thumbHeight, imagesx($img), imagesy($img));
if (!file_exists($pathToThumbs)) {
}
imagepng($thumb, "{$pathToThumbs}{$thumbWidth}x{$thumbHeight}-{$imgName}");
return $thumb;
}
Change:
imagepng($thumb, "{$pathToThumbs}{$thumbWidth}x{$thumbHeight}-{$imgName}");
return $thumb;
To:
$outPath = "{$pathToThumbs}{$thumbWidth}x{$thumbHeight}-{$imgName}";
imagepng($thumb, $outPath);
return $outPath;
The reason why it does not work is because at the first call you are returning $thumb which is returned by imagecreatetruecolor() call.
The problem is it returns an image identifier, not file name. Check the documentation
You can easily fix your code by changing the last line
//return $thumb;
return $resizedPath;
On your first run, you return the resource that you pass in to the imagepng function. On second run, you return the path.
imagepng($thumb, "{$pathToThumbs}{$thumbWidth}x{$thumbHeight}-{$imgName}");
// $thumb is a resource.
return $thumb;
Make the function return the path in both cases.
Want to take image from own server rotate certain angle and save the image.
Image file $filename = 'kitten_rotated.jpg'; With echo '<img src='.$filename.'>'; i see the image.
Then
$original = imagecreatefromjpeg($filename);
$angle = 90.0;
$rotated = imagerotate($original, $angle, 0);
Based on this https://stackoverflow.com/a/3693075/2118559 answer trying create image file
$output = 'google.com.jpg';
If i save the same image with new file name, all works
file_put_contents( $output, file_get_contents($filename) );
But if i try to save rotated image, then file_put_contents(): supplied resource is not a valid stream resource.
file_put_contents( $output, $rotated );
Here https://stackoverflow.com/a/12185462/2118559 read $export is going to be a GD image handle. It is NOT something you can simply dump out to a file and expect to get a JPG or PNG image.. but can not understand how to use the code in that answer.
How to create image file from $rotated?
Tried to experiment, based on this http://php.net/manual/en/function.imagecreatefromstring.php
$fh = fopen( 'some_name.png' , 'w') or die("can't open file");
fwrite($fh, $data );
fclose($fh);
Does it means that need something like
$data = base64_encode($rotated);
And then write in new file?
I have not tested this, but I think you need to encode the image as base 64 first.
If you check the string from any Image URL, you'd see data:image/png;base64, preceding the hash. Prepending this to your image string and saving.
Here is a function that may help, based on what you already have:
// Function settings:
// 1) Original file
// 2) Angle to rotate
// 3) Output destination (false will output to browser)
function RotateJpg($filename = '',$angle = 0,$savename = false)
{
// Your original file
$original = imagecreatefromjpeg($filename);
// Rotate
$rotated = imagerotate($original, $angle, 0);
// If you have no destination, save to browser
if($savename == false) {
header('Content-Type: image/jpeg');
imagejpeg($rotated);
}
else
// Save to a directory with a new filename
imagejpeg($rotated,$savename);
// Standard destroy command
imagedestroy($rotated);
}
// Base image
$filename = 'http://upload.wikimedia.org/wikipedia/commons/b/b4/JPEG_example_JPG_RIP_100.jpg';
// Destination, including document root (you may have a defined root to use)
$saveto = $_SERVER['DOCUMENT_ROOT']."/images/test.jpg";
// Apply function
RotateJpg($filename,90,$saveto);
If you want to save image just use one of GD library functions: imagepng() or imagepng().
imagerotate() returns image resource so this is not something like string.
In your case just save rotate image:
imagejpg($rotated, $output);
And now You can use $output variable as your new filename to include in view like before:
echo '<img src='.$output.'>';
Don't forget to include appropriate permissions in directory where You're saveing image.
Our server is saving EXIF data to every file saved with imagejpeg(). As far as I know, this is not the default behavior (or even possible, from what I've read). But, it is occurring, and due to the FileDateTime information being included (and using the time of save), it is breaking functionality in our upload/approval system (md5_file() returns a different value for the exact same image due to FileDateTime always being different).
Is there a way to prevent imagejpeg() from saving EXIF data for images by default?
Server Information
CentOS 5
Parallels Plesk Panel 10.4.4
GD Version: bundled (2.0.34 compatible)
PHP 5.3
Code
<?php
public function upload_book_cover($book, $cover, $filename = NULL, $approved = NULL){
global $c_consummo, $user;
$approved = bool($approved, true, true);
if(filesize($cover)>5242880){
return false; // Too large;
}
$max_width = 450;
$cover_info = getimagesize($cover);
if(!$this->is_valid_book_cover_type($cover_info['mime'])){
return false; // Invalid image type
}
$width = $cover_info[0];
$height = $cover_info[1];
if($width<200){
return false; // Too small
} elseif($width>1500){
return false; // Too wide
}
$original_cover = false;
switch($cover_info[2]){
case IMAGETYPE_GIF:
$original_cover = imagecreatefromgif($cover);
break;
case IMAGETYPE_JPEG:
$original_cover = imagecreatefromjpeg($cover);
break;
case IMAGETYPE_PNG:
$original_cover = imagecreatefrompng($cover);
break;
case IMAGETYPE_BMP:
$original_cover = imagecreatefrombmp($cover);
break;
}
if(!$original_cover){
return false; // Unsupported type
}
if($width>$max_width){
$new_width = $max_width;
} else {
$new_width = $width;
}
$new_height = round($height*($new_width/$width));
$new_cover = imagecreatetruecolor($new_width, $new_height);
if(!$new_cover){
return false; // Could not create true color image
}
if(!imagecopyresampled($new_cover, $original_cover, 0, 0, 0, 0, $new_width, $new_height, $width, $height)){
return false; // Could not copy image
}
if(!imagejpeg($new_cover, $cover, 100)){
return false; // Image could not be saved to tmp file
// This is adding *new* EXIF data to images by itself
}
$file_hash = md5_file($cover);
$duplicate_book_cover = $this->find_duplicate_book_cover($book, $file_hash);
if($duplicate_book_cover){
return $duplicate_book_cover;
}
$file_id = $c_consummo->upload_file($cover, $filename);
...
}
It looks like you have tried several things here, but lets try one more.
Do you EVER need EXIF information in your application?
If not lets take out support for EXIF and see if that completely removes it.
If it does not remove it, then perhaps the functions are reading it from the existing photos and then just blindly including it in the file that is written.
You can know for sure by printing out the EXIF information at each step of process
No idea why EXIF data is being written - so the following may help you remove it.
One suggestion is to run something as a command on the server - it will need some installation: http://hacktux.com/read/remove/exif - then run throuhg EXEC from PHP.
There's also solution posted here that uses ImageMagick if you also have that installed (or cen get it installed: Remove EXIF data from JPG using PHP (but note warning about colour)
Otherwise, the other suggestion is as above, try turning off the EXIT extension.
Sorry if they don't help, but you did ask for any suggestions.
Apparently, GD doesn't like when the path to the input / output file is the same, but the credit isn't mine. To fix, use a new (tmp) file to save the newly created image to:
<?php
...
if(!imagecopyresampled($new_cover, $original_cover, 0, 0, 0, 0, $new_width, $new_height, $width, $height)){
return false; // Could not copy image
}
// Create a tmp file.
$cover_new = tempnam('/tmp', 'cover-');
// Use $cover_new instead of $cover
if(!imagejpeg($new_cover, $cover_new, 100)){
return false; // Image could not be saved to tmp file
}
// Use $cover_new instead of $cover
$file_hash = md5_file($cover_new);
$duplicate_book_cover = $this->find_duplicate_book_cover($book, $file_hash);
if($duplicate_book_cover){
return $duplicate_book_cover;
}
// Use $cover_new instead of $cover
$file_id = $c_consummo->upload_file($cover_new, $filename);
...
Read this, maybe it will help:
http://www.php.net/manual/en/function.imagecreatefromjpeg.php#65656
and this:
http://www.sentex.net/~mwandel/jhead/usage.html
You could possibly convert the jpeg to a gif first, then convert the gif back to a jpeg. In doing so, my understanding is that you would destroy the EXIF data. It's a hack, but it should work.
The only thing that spring to mind is, that you could ignore the EXIF data and just make your hash from something else? My suggestion would be to try either hashing the raw output without saving to a file (here outputting in gif format -which makes a smaller, 8-bit image for performance- to an output buffer and hashing the buffer content)
if(!imagecopyresampled(...)) {...}
ob_start();
imagegif($new_cover);
$file_hash = md5(ob_get_contents());
ob_end_clean();
if(!imagejpeg($new_cover, $cover, 100)) {...}
Or you could build a string containing only the pixel information and hash that (here done by accessing each pixel and appending its value to a string, in reverse for performance)
$pixels = '';
for($x=$new_width-1; $x>=0; $x--) {
for($y=$new_height-1; $y>=0; $y--) {
$pixels .= imagecolorat($new_cover, $x, $y);
}
}
$file_hash = md5($pixels);
For performance, you could also choose only to take samples from the image, as this should work just as well or maybe even better (here sampling every 5th pixel of every 5th row)
$pixels = '';
for($x=$new_width-1; $x>=0; $x-=5) {
for($y=$new_height-1; $y>=0; $y-=5) {
$pixels .= imagecolorat($new_cover, $x, $y);
}
}
$file_hash = md5($pixels);
I hope some of this will work (as I can't test it right now) or at least will help you find the way that works for you :)
This is a bit of a hack, but it will work, just do this after your switch() statement:
$original_cover = imagerotate($original_cover,360,0);
GD will strip any EXIF data out, as it doesn't support it.
You could try using imagecreatefromjpeg on the image created with imagejpeg and replacing with the newly created one.
$res = imagecreatefromjpeg($filename) to load the image, then imagejpeg($res, $filename, QUALITY)to rerender it.
You can use imagemagick too:
$img = new Imagick($image);
$img->stripImage();
$img->writeImage($image);
$img->clear();
$img->destroy();
Your PHP must be compiled in with --enable-exif.
Try to disable globally EXIF functionality by recompiling PHP without this option.