Imagick - Can't read image files from URL. - php

I'm using this snippet for reading images on different websites:
$image = new Imagick('http://lp.hm.com/hmprod?set=key[source],value[/model/2012/P01 05156 06204 80 1175 4.jpg]&set=key[rotate],value[]&set=key[width],value[]&set=key[height],value[]&set=key[x],value[]&set=key[y],value[]&set=key[type],value[STILL_LIFE_FRONT]&call=url[file:/product/large]');
But sometimes, I get an error like this (about 20% of the time):
ImagickException
Unable to read the file: http://lp.hm.com/hmprod?set=key[source],value[/model/2012/P01 05156 06204 80 1175 4.jpg]&set=key[rotate],value[]&set=key[width],value[]&set=key[height],value[]&set=key[x],value[]&set=key[y],value[]&set=key[type],value[STILL_LIFE_FRONT]&call=url[file:/product/large]
Imagick->__construct()
The error seems to be consistent through this whole domain, but sometimes it's different from image to image on the same domain.
Questions
Why is this a problem?
How can we fix it?
Is there an alternative solution?

STEP 1 : GET URL
$url = 'http://blablabla.com/blabla.jpeg';
STEP 2 : Save blog content to a variable
$image = file_get_contents($url);
STEP 3 : Create Imagick object
$img = new Imagick();
STEP 4 : Instruct imagick object to read blob content of the image
$img -> readImageBlob($image);
STEP 5 : Save (or do operations) on image
$img -> writeImage('/var/www/html/uploads/img.jpg');
STEP 6 : Destroy imagick instance
$img -> destroy();

So I figured out I needed to encode the url properly. I'm not sure if this code is optimal, but it works.. and could hopefully help someone else.
$parsedUrl = parse_url('http://lp.hm.com/hmprod?set=key[source],value[/model/2012/P01 05156 06204 80 1175 4.jpg]&set=key[rotate],value[]&set=key[width],value[]&set=key[height],value[]&set=key[x],value[]&set=key[y],value[]&set=key[type],value[STILL_LIFE_FRONT]&call=url[file:/product/large]');
$info = pathinfo($parsedUrl['path']);
$dirname = explode('/', $info['dirname'] ?: '');
$dirname = array_filter($dirname, 'strlen');
$dirname = array_map('urlencode', $dirname);
$dirname = implode('/', $dirname);
$basename = urlencode($info['basename'] ?: '');
$path = array_filter(array($dirname, $basename), 'strlen');
$path = '/' . implode('/', $path);
$query = explode('&', $parsedUrl['query'] ?: '');
foreach ($query as &$set)
{
$set = explode('=', $set, 2);
$set = array_map('urlencode', $set);
$set = implode('=', $set);
}
$query = implode('&', $query);
$uri = array_filter(array($path, $query), 'strlen');
$uri = implode('?', $uri);
$fragment = urlencode($info['fragment'] ?: '');
$uri = array_filter(array($uri, $fragment), 'strlen');
$uri = implode('#', $uri);
$scheme = $parsedUrl['scheme'] ?: '';
$host = $parsedUrl['host'] ?: '';
$url = array_filter(array($scheme, $host), 'strlen');
$url = implode('://', $url);
$url .= $uri;
$image = new Imagick($url);
OBS!
This code will leave notifications.

Try to use urlencode function for encode special chars of url:
$image = new Imagick(urlencode('http://lp.hm.com/hmprod?set=key[source],value[/model/2012/P01 05156 06204 80 1175 4.jpg]&set=key[rotate],value[]&set=key[width],value[]&set=key[height],value[]&set=key[x],value[]&set=key[y],value[]&set=key[type],value[STILL_LIFE_FRONT]&call=url[file:/product/large]'));
Or if not work, try this:
$content = file_get_contents(urlencode('http://lp.hm.com/hmprod?set=key[source],value[/model/2012/P01 05156 06204 80 1175 4.jpg]&set=key[rotate],value[]&set=key[width],value[]&set=key[height],value[]&set=key[x],value[]&set=key[y],value[]&set=key[type],value[STILL_LIFE_FRONT]&call=url[file:/product/large]'));
$image = new Imagick($content);

I just encountered a similar issue. I was using file_get_contents() and was getting the same "ImagickException The filename is too long". The fix for me was finding the tmp directory and setting the correct permissions for it.

Related

How can i convert a FilePath to a File in PHP/Laravel?

For example I have this file:
$thumbnail = 'http://www.example.com/pic.jpeg';
I try this:
$thumbnail = file_get_contents($thumbnail);
dd($thumbnail->getClientOriginalExtension());
I got this error:
"Call to a member function getClientOriginalExtension() on string"
Are you storing it on disk? This worked in my tester.
use Storage;
$url = "http://www.google.co.in/intl/en_com/images/srpr/logo1w.png";
$contents = file_get_contents($url); $name = substr($url, strrpos($url, '/') + 1);
Storage::put($name, $contents);

Openssl_pkcs7_sign(): error opening file

it's my first time doing signing of cert using openssl. Keep hitting the above error and tried realpath() and appending file:// but still can't get openssl to sign the profile. I don't understand how this works. Any insights would be appreciated.
Edit1: I'm not sure which file is the problematic one. The error messages wasn't specific enough. Is there a way to tell?
Code and screenshots below:
function signProfile()
{
$filename = "./template.mobileconfig";
$filename = realpath($filename);
$outFilename = $filename . ".tmp";
$pkey = dirname(__FILE__) . "/PteKey.key";
$pkey = realpath($pkey);
$certFile = dirname(__FILE__) . "/CertToSign.crt";
$certFile = realpath($certFile);
// try signing the plain XML profile
if (openssl_pkcs7_sign($filename, $outFilename, 'file://'.$certFile, array('file://'.$pkey, ""), array(), 0, ""))
{
// get the data back from the filesystem
$signedString = file_get_contents($outFilename);
// trim the fat
$trimmedString = preg_replace('/(.+\n)+\n/', '', $signedString, 1);
// convert to binary (DER)
$decodedString = base64_decode($trimmedString);
// write the file back to the filesystem (using the filename originally given)
$fh = fopen($filename, 'w');
fwrite($fh, $decodedString);
fclose($fh);
// delete the temporary file
unlink($outFilename);
return TRUE;
}
else
{
return FALSE;
}
}
Remove unwanted fields if not used in
openssl_pkcs7_sign($mobileConfig, $tmpMobileConfig, $certFile, array($pkey, ""), array());
Make sure file paths are correctly supplied.
require_once('variables.php'); //stores abs path to $tmpMobileConfig/$pteKeyPath/$CertToSignPath
$prepend = "file://";
$mobileConfig = realpath("./template.mobileconfig");
$pkey = $prepend . $pteKeyPath;
$pkey = str_replace('\\', '/', $pkey);
$certFile = $prepend . $CertToSignPath;
$certFile = str_replace('\\', '/', $certFile);
$isSignedCert = openssl_pkcs7_sign($mobileConfig, $tmpMobileConfig, $certFile, array($pkey, ""), array());

Looping through CSV and parsing a JSON query using each result

So despite hours of fiddling I cannot understand why my JSON query only returns a result for the last line in the CSV/TXT files I am trying to parse.
Here is the code:
//Enter API Key Here
$api_key = 'AIzaSyB9Dq3w1HCxkS5qyELI_pZuTmdK8itOBHo';
$origin = 'RG12 1AA';
$output_type = 'json'; //xml or json
$csv_location = 'http://www.naturedock.co.uk/postcodes.csv';
//Do not edit
$base_url = 'https://maps.googleapis.com/maps/api/directions/';
$origin_url = '?origin=';
$destination_url = '&destination=';
$end_url = '&sensor=false&key=';
$page = join("",file("$csv_location"));
$kw = explode("\n", $page);
for($i=0;$i<count($kw);$i++){
$destination = $kw[$i];
echo $destination;
$raw_url = $base_url . $output_type . $origin_url . $origin . $destination_url . $destination . $end_url . $api_key;
$request_url = str_replace(' ', '', $raw_url);
$getJson = file_get_contents($request_url);
$routes = json_decode($getJson);
$result = $routes->routes[0]->legs[0]->distance->value;
echo $result . '<br>';
}
The result I get looks like this:
Distance by Post Code Generator v0.1 by Phil Hughes
RG12 0GA
RG12 0GB
RG12 0GC
RG12 0GD4066
Where the '4066' is the correct variable for RG12 0GD postcode but none of the others return results as you can see.
Please help.
Your
join("",file("$csv_location"));
concatenated all lines feom the file to a single line without separator. The following explode() sees no newlines any more. So you are working on one line only. count($kw) always evaluates to 1 and your loop runs only one time.

Parsing url and routing issues

www.foo.com/Base/index.php/controller/method/
This is my url, I need to get only "controller/method" part out of it - is there any elegant way to achieve this?
parse_url($url, PHP_URL_PATH)
This would be great, but it returns the whole "Base/index.php/controller/method" part.
$url = "http://www.foo.com/Base/index.php/controller/method/";
$path = parse_url($url, PHP_URL_PATH);
$parts = explode("/", $path);
$index = array_search("index.php", $parts);
$controller = $parts[$index+1];
$method = $parts[$index+2];
You did not provide any additional information about url format. But as example, you may use regular expressions with preg_match():
$url = "http://www.foo.com/Base/index.php/controller/method/";
preg_match ("/^.*Base\/index.php\/([a-zA-Z0-9_]*)\/([a-zA-Z0-9_]*)\/?/", $url, $data);
$controller = $data[1];
$method = $data[2];

How can I get the Domain.ext from url? PHP prase

if we have
$url = "http://subdomain.domin.ext/somepath/file.php";
how to get the domain.ext
when I used
$parse = parse_url($url);
$domin = $parse[host];
then
echo "$domain"; //this returns subdomain.domin.ext
is there any idea to get domain.ext?
$url = "http://subdomain.domin.ext/somepath/file.php";
$parse = parse_url($url);
$domain = $parse['host'];
$lastDot = strrpos($domain,'.');
$ext = substr($domain,$lastDot+1);
This will get you "ext" (e.g. "com" or "gov"). In the case of something like amazon.co.uk, it will give you "uk". If you need "co.uk", you will need to add logic to detect certain TLDs (e.g. "uk") and go to the second dot on those cases.
<?php
$url = "http://subdomain.domain.ext/somepath/file.php";
$parse = parse_url($url);
$domain = substr(strrchr($parse['host'], '.'), 1);
$domain = substr(strrchr(substr($parse['host'], 0, -strlen($domain)), '.'), 1). '.'. $domain;
if(in_array(strstr($domain, '.', true), array('co', 'com', 'net', 'org', 'edu', 'gov', 'mil')))
{
$domain = substr(strrchr(substr($parse['host'], 0, -strlen($domain)), '.'), 1). '.'. $domain;
}
?>
If you have a specific domain with different TLDs, like mysite with .co.uk and .com, than you can basically do the following:
$url = 'http://mysite.co.uk/some-dir/';
$domain_pos = strpos($url, 'mysite');
$domain = substr($url, $domain_pos);
$ext_pos = strpos($domain, '/');
if($ext_pos !== false) { // extra check for paths/sub-dirs
$domain = substr($domain, 0, $ext_pos);
}
echo $domain;
Returns mysite.co.uk or whatever TLD that gets assigned to the $url.
Note the extra check for paths and sub directories. :)

Categories