I've written a script that searches through exiting legal case dockets for things like "motion to intervene" and "motion to compel". If the regular expression returns true, then it looks to see if there is a scanned image of the document online for public use. That image is a TIFF file, but not an ordinary tiff file. Here is a link to an example of what I'm trying to copy to my own server.
http://www.oscn.net/applications/oscn/getimage.tif?submitted=true&casemasterid=2565129&db=OKLAHOMA&barcode=1012443256
Here is the error you get if you only try to look at the http://www.oscn.net/applications/oscn/getimage.tif
It is a TIFF file but dynamic. I've used the fopen(), CURL, etc without success. I've used these types of functions with JPG images from random sites just to check to make sure that my server allowed this type of stuff and it worked.
I don't have PDFlib installed on the server (I checked the PEAR and it's not available there either, though I'm not 100% sure that is where it would be.) My host uses cPanel. The server is running Apache. I'm not sure where else to look for a solution to this problem.
I've seen some solutions that used PDFlib but each of those grabbed a normal TIFF image, not one that was dynamically created. My thought though is that it shouldn't matter if I can get the image data to stream, shouldn't I be able to use fopen() and write or buffer that data into my own .tif file?
Thanks for any input and Happy Thanksgiving!
UPDATE: The issue wasn't with CURL, it was with the URL I scraped to pass to CURL. When I printed the $url to the screen, it looked right, but it wasn't. Somewhere & was turned into &, which then threw off CURL because it was fetching an invalid URL (invalid at least according to the remote server where the TIF file is).
For those of you finding this later, here is the script that works perfectly.
//*******************************************************************************
$url = 'http://www.oscn.net/applications/oscn/getimage.tif"
$url .= '?submitted=true&casemasterid=2565129&db=OKLAHOMA&barcode=1016063497';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url); // set the url
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // get the transfer as a string, rather than output it directly
print "Attempting to fetch file...\n";
$img = curl_exec($ch); // get the image
//I used the time() so that in testing I would know when a new file was created rather than always overwriting the old file. This will be changed for final version
if($img){
$fh = fopen('oscn_docs/' . time(). '.tif', 'w'); // this will simply overwrite the file. If that's not what you want to do, you'll have to change the 'w' argument!
if($fh){
$byteswritten = fwrite($fh, $img);
fclose($fh);
}else{
print "Unable to open file.\n";
}
}else{
print "Unable to fetch file.\n";
}
print "Done.\n";
exit(0);
//*******************************************************************************
jarod
For those of you finding this later, here is the script that works perfectly.
//*******************************************************************************
$url = 'http://www.oscn.net/applications/oscn/getimage.tif"
$url .= '?submitted=true&casemasterid=2565129&db=OKLAHOMA&barcode=1016063497';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url); // set the url
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // get the transfer as a string, rather than output it directly
print "Attempting to fetch file...\n";
$img = curl_exec($ch); // get the image
//I used the time() so that in testing I would know when a new file was created rather than always overwriting the old file. This will be changed for final version
if($img){
$fh = fopen('oscn_docs/' . time(). '.tif', 'w'); // this will simply overwrite the file. If that's not what you want to do, you'll have to change the 'w' argument!
if($fh){
$byteswritten = fwrite($fh, $img);
fclose($fh);
}else{
print "Unable to open file.\n";
}
}else{
print "Unable to fetch file.\n";
}
print "Done.\n";
exit(0);
//*******************************************************************************
Related
I want to copy an image from an another server, but it doesn't work and i don't know why. Here is my code:
if(copy('http://demo.swyp.fr/mod_traffiq/thumb/LQ1009C/LQ143559C/LQ157553C-71x100.jpg', 'zzz.jpg')) {
echo "Copy success!";
}else{
echo "Copy failed.";
}
It always returns failed.
You are using the copy function. Although this method works with both remote sources and destinations, you are encouraged to use the file_put/get_contents-methods (see documentation quote below).
$image = file_get_contents('http://demo.swyp.fr/mod_traffiq/thumb/LQ1009C/LQ143559C/LQ157553C-71x100.jpg');
file_put_contents('zzz.jpg', $image);
From the file_get_contents documentation:
file_get_contents() is the preferred way to read the contents of a file into a string. It will use memory mapping techniques if supported by your OS to enhance performance.
Also note:
A URL can be used as a filename with this function if the fopen wrappers have been enabled.
However, if fopen remote URL is not turned on in your settings, you might test with cURL:
$ch = curl_init('http://demo.swyp.fr/mod_traffiq/thumb/LQ1009C/LQ143559C/LQ157553C-71x100.jpg');
$fp = fopen('zzz.jpg', 'wb');
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_exec($ch);
curl_close($ch);
fclose($fp);
There could be other PHP settings (or server configurations) which disables all of these code snippets from running. If this does not work, then it is a matter of configuration issues instead.
I'm encrypting imagea into base64 then storing them in the database. I then print the images using PHP, but sometimes I get a corrupted image. If I put the same code in an HTML file, or if I refresh the page many times, then it works.
This is my corrupted image:
My HTML looks like this:
<img src="data:image/png;_encrypteddata_" />
NOTE: _encrypteddata_ is my encrypted image (I cannot post that huge data here)
It works fine, but sometimes it shows a continuously corrupted image with the same data. Is it having problem with browser or base64?
I'm using image/png for all the icons. Would that cause any problems?
I think it's coming from the browser.
NB :Retreiving image data from the database on every page load can be slow.
Try writing an image file on your filesystem with the data and link to this file in your HTML. It will be faster and more robust.
Basically base64 get much memory for storing encrypted data especially images so whenever you get that little bit huge data from database it takes some times to be loaded . sometimes browser does not wait much time to decrypt so you could see corrupted images.
You better to store your images in the local file system rather than storing into the database. it will speed up your process.
use this code for store your data into local file system
function get_image($image_url, $localPathToStore)
{
echo $url . "<br>" . $saveto;
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1);
$raw = curl_exec($ch);
curl_close($ch);
if (file_exists($saveto)) {
unlink($saveto);
}
$fp = fopen($saveto, 'x');
fwrite($fp, $raw);
fclose($fp);
}
I got this solution
<img src='data:image/;base64,_encrypteddata_'/>
From http://www.kingpabel.com/php-base64_encode/
I have a file uploading script running on my server which also features remote uploads.. Everything works fine but I am wondering what is the best way to upload via URL. Right now I am using fopen to get the file from the remote url pasted in the text box named "from". I have heard that fopen isn't the best way to do it. Why is that?
Also I am using file_get_contents to get the file size of the file from the URL. I have heard that curl is better on that part. Why is that and also how can I apply these changes to this script?
<?php
$from = htmlspecialchars(trim($_POST['from']));
if ($from != "") {
$file = file_get_contents($from);
$filesize = strlen($file);
while (!feof($file)) {
$move = "./uploads/" . $rand2;
move_upload($_FILES['from']['tmp_name'], $move);
$newfile = fopen("./uploads/" . $rand2, "wb");
file_put_contents($newfile, $file);
}
}
?>
You can use filesize to get the file size of a file on disk.
file_get_contents actually gets the file into memory so $filesize = strlen(file_get_contents($from)); already gets the file, you just don't do anything with it other than find it size. You can substitute for you fwrite call file_put_contents;
See: file_get_contents and file_put_contents .
curl is used when you need more access to the HTTP protocol. There are many questions and examples on StackOverflow using curl in PHP.
So we can first download the file, in this example I wll use file_get_contents, get its size, then put the file in the directory on your local disk.
$tmpFile = file_get_contents($from);
$fileSize = strlen($tmpFile);
// you could do a check for file size here
$newFileName = "./uploads/$rand2";
file_put_contents($newFileName, $tmpFile);
In your code you have move_upload($_FILES['from']['tmp_name'], $move); but $_FILES is only applicable when you have a <input type="file"> element, which it doesn't seem you have.
P.S. You should probably white-list characters that you allow in a filename for instance $goodFilename = preg_replace("/^[^a-zA-Z0-9]+$/", "-", $filename) This is often easier to read and safer.
Replace:
while (!feof($file)) {
$move = "./uploads/" . $rand2;
move_upload($_FILES['from']['tmp_name'], $move);
$newfile = fopen("./uploads/" . $rand2, "wb");
file_put_contents($newfile, $file);
}
With:
$newFile = "./uploads/" . $rand2;
file_put_contents($newfile, $file);
The whole file is read in by file_get_contents the whole file is written by file_put_contents
As far as I understand your question: You want to get the filesize of a remote fiel given by a URL, and you're not sure which solution ist best/fastest.
At first, the biggest difference between CURL, file_get_contents() and fread() in this context is that CURL and file_get_contents() put the whole thing into memory, while fopen() gives you more control over what parts of the file you want to read. I think fopen() and file_get_contents() are nearly equivalent in your case, because you're dealing with small files and you actually want to get the whole file. So it doesn't make any difference in terms of memory usage.
CURL is just the big brother of file_get_contents(). It is actually a complete HTTP-Client rather than some kind of a wrapper for simple functions.
And talking about HTTP: Don't forget there's more to HTTP than GET and POST. Why don't you just use the resource's meta-data to check it's size before you even get it? That's one thing the HTTP method HEAD is meant for. PHP even comes with a built in function for getting the headers: get_headers(). It has some flaws though: It still sends a GET request, which makes it probably a little slower, and it follows redirects, which may cause security issues. But you can fix this pretty easily by adjusting the default context:
$opts = array(
'http' =>
array(
'method' => 'HEAD',
'max_redirects'=> 1,
'ignore_errors'=> true
)
);
stream_context_set_default($opts);
Done. Now you can simply get the headers:
$headers = get_headers('http://example.com/pic.png', 1);
//set the keys to lowercase so we don't have to deal with lower- and upper case
$lowerCaseHeaders = array_change_key_case($headers);
// 'content-length' is the header we're interested in:
$filesize = $lowerCaseHeaders['content-length'];
NOTE: filesize() will not work on a http / https stream wrapper, because stat() is not supported (http://php.net/manual/en/wrappers.http.php).
And that's pretty much it. Of course you can achieve the same with CURL just as easy if you like it better. The approach would be same (reding the headers).
And here's how you get the file and it's size (after downloading) with CURL:
// Create a CURL handle
$ch = curl_init();
// Set all the options on this handle
// find a full list on
// http://au2.php.net/manual/en/curl.constants.php
// http://us2.php.net/manual/en/function.curl-setopt.php (for actual usage)
curl_setopt($ch, CURLOPT_URL, 'http://example.com/pic.png');
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// Send the request and store what is returned to a variable
// This actually contains the raw image data now, you could
// pass it to e.g. file_put_contents();
$data = curl_exec($ch);
// get the required info about the request
// find a full list on
// http://us2.php.net/manual/en/function.curl-getinfo.php
$filesize = curl_getinfo($ch, CURLINFO_SIZE_DOWNLOAD);
// close the handle after you're done
curl_close($ch);
Pure PHP approach: http://codepad.viper-7.com/p8mlOt
Using CURL: http://codepad.viper-7.com/uWmsYB
For a nicely formatted and human readable output of the file size I've learned this amazing function from Laravel:
function get_file_size($size)
{
$units = array('Bytes', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB');
return #round($size / pow(1024, ($i = floor(log($size, 1024)))), 2).' '.$units[$i];
}
If you don't want to deal with all this, you should check out Guzzle. It's a very powerful and extremely easy to use library for any kind HTTP stuff.
The following code retrieves an image and saves it to a local folder. A jpg file is indeed saved to local disk, with around 40KB filesize (seems correct). When I put the local path in an img tag, the file does not display.
Firebug > Inspect Element shows a size of 0 X 0 and I'm unable to view the image when saved to my desktop.
file_put_contents, file_get_contents and getimagesize don't return FAILs. $url IS a valid image. The problem is just saving it locally, the file seems to be corrupt - how come?
$url = $image->request_url; //the image generated on the remote server
//print_r(getimagesize($url)); die;
$img = 'thumbalizr/cache/screenshot_' . $row['id'] . '.jpg'; //path to our local cache folder + unique filename
if( !$captured_file = file_get_contents($url) ) die('file could not be retrieved');
elseif( !file_put_contents($img, $captured_file, FILE_APPEND) ) die('file could not be written to local disk'); //write the image to our local cache
"Are you sure the path is correct? Have you tried an absolute path?" YES
"Have you checked that the image is downloaded correctly, perhaps with another utility (e.g. ftp, diff)?" I can download the img via ftp but it does not open on my local computer either.
"What do you get if you call the URL directly in the browser?" FF just prints out the URL instead of showing the image
"Why are you using FILE_APPEND? if the target already exists, this writes to the end, which will naturally give you a corrupt image" I removed FILE_APPEND, no difference
"source and final extension are the same?" Yes I tried with jpg, jpeg and png - no difference
"First of all, example code is wrong. Can't use $capture_file in file_put_content because that variable is not defied becouso of if else if block logic." - WRONG, that code does run!
"Can you look into the image file" - no! Although the file has a realistic file size and I can download it, it's impossible to open it.
First off check the files you're been downloading in a text editor to see if you're getting HTML error pages instead of binary image data.
Second, I would use curl for this as it provides better success/error information. Here's your example modified to use it.
//path to our local cache folder + unique filename
$img_path = 'thumbalizr/cache/screenshot_' . $row['id'] . '.jpg';
$c = curl_init();
curl_setopt($c, CURLOPT_URL, $image->request_url);
curl_setopt($c, CURLOPT_HEADER, 0);
curl_setopt($c, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($c, CURLOPT_AUTOREFERER, true);
curl_setopt($c, CURLOPT_BINARYTRANSFER, true);
curl_setopt($c, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($c, CURLOPT_FORBID_REUSE, true);
// curl can automatically write the file out for you
curl_setopt($c, CURLOPT_FILE, $img_path);
// You can get more elaborate success/error info from
// curl_getinfo() http://www.php.net/manual/en/function.curl-getinfo.php
if (!curl_exec($c)) {
die('file could not be retrieved');
}
The following code transfers an image that is created on the fly from a server to a client site using cURL. It stopped working recently and have not been able to find out what the problem is:
// get_image.php
ob_start();
// create a new CURL resource
$ch = curl_init();
// set URL and other appropriate options
curl_setopt($ch, CURLOPT_URL, 'url/to/image.php');
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_BINARYTRANSFER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// set timeouts
set_time_limit(30);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
// open a stream for writing
$outFile = fopen($fileDestination, 'wb');
curl_setopt($ch, CURLOPT_FILE, $outFile);
// grab file from URL
curl_exec($ch);
fclose($outFile);
// close CURL resource, and free up system resources
curl_close($ch);
ob_end_clean();
//image.php
/*
* Create image based on client site ...
*/
$filePath = 'path/to/image.png'
$imageFile = file_get_contents($filePath);
header("content-type: image/png");
echo $imageFile;
unlink($filePath);
The file get_image.php is located in a client site and calls the file image.php located in my server.
After running this code the image in the client site is about 7 bytes larger than the original, these bytes seem to be line breaks. After debugging for several hours I found out that these bytes are added when I echo $imageFile. If the 7 bytes are manually removed from the resulting image, the image displays correctly.
There are no errors nor exceptions thrown. The image created in the server is created with no issues. The only output in FF is "The image 'url/to/image.php' cannot be displayed, because it contains errors"
I am not sure what is causing this. Help is greatly appreciated.
Onema
UPDATE:
http://files.droplr.com/files/38059844/V5Jd.Screen%20shot%202011-01-12%20at%2012.17.53%20PM.png
http://files.droplr.com/files/38059844/QU4Z.Screen%20shot%202011-01-12%20at%2012.23.37%20PM.png
Some things to check.
That both files are stored without BOMs
That '<?php' are the first five characters and '?>' the last two in both files.
That when you remove the ob_start() and ob_end-clean(() it should show no error messages.
If you put the unlink before the genereation, you can see the genereated file - check it is valid.
You might want to start the practice of leaving the final ?> from the end of your files - it isn't necessary, and can cause problems if there is whitespace and newlines following the php delimiter.