Count image views - php

I would like to have code for an image that counts the number of times the image is viewed, regardless of what site the image is found on. I want to use the img src tag, and have src point to a php page that counts that view and then returns the image to be viewed. I was thinking something like this:
<img src="www.mywebsiteurl.com/something.php" />
How would I go about writing "something.php" so that it returns the proper image file? I know how to record the page view, but if I must do something different in this case, please tell me.

Your script needs to:
Record the hit.
Set the content type of the output ( header('Content-Type: image/jpeg'); )
Output the image ( readfile( $path_to_image ) );
For examples, please see the readfile documentation and Output an Image in PHP.

Loading images / files from php is slow than normal loading files.
Main cons:
Images can't be cached due to dynamic query most browser dont support on dynamic queries.
Overhead on sever and apache both.
If you use database and want to increment column after image loads than a person can load your image again and again. So you need to use conditions on every query.
Alternative Solution
Enter this code in footer of page on which you want to show images
A ajax call
$.get("inc_img_view.php?img_id="+<?php echo $img_id; ?>);

This is the most barebones version you can have:
<?php
header('Content-type: image/jpeg');
readfile('somepic.jpg');

You can call an image using a URL similar to: www.mywebsiteurl.com/image_renderer.php?url=url_to_image.
image_rendered.php:
<?php
header("Content-Type: image/jpeg");
$url = urldecode($_GET['url']);
$headers = array(
"GET ".$url." HTTP/1.1",
"Content-Type: text/xml; charset=UTF-8",
"Accept: text/xml",
"Cache-Control: no-cache",
"Pragma: no-cache"
);
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, false);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
$r = curl_exec($ch);
// you can connect to your database and increment the number of times this image was viewed
echo $r;
?>
Hope this will point you into the right direction.

Yes you're on a good start.
I'd do something like this
<img src="www.mywebsiteurl.com/image_counter.php?src=image.jpg" />
In image_counter.php, take $src = $_GET['src'] for image source.
Then +1 the hit for that image in the database.
Then do
header('Content-type: image/jpeg');
readfile($src);

Something like this should work:
<?php
$file = $_GET['img'];
$path = "images/";
// do an increment of views on the image here - probably in a database?
$exifImageType = exif_imagetype($path.$file);
if ($exifImageType !== false) {
$type = image_type_to_mime_type($exifImageType);
}
header('Content-Type: $type');
echo file_get_contents($path.$file);
Note: this would make something like:
<img src="getimage.php?img=image.jpg" />
show the correct image after incrementing the views.
You could always add some .htaccess to make all calls to /images/anything go through your image file. It'd mean you could keep the URL looking as though it's getting an actual image file (e.g. /images/logo.jpg would be re-written to actually go through getimage.php?img=logo.jpg)

Related

file_get_contents not outputting svg

I'm trying to grab an svg file with php and output it onto a page. Site is built on Wordpress.
<?php
echo file_get_contents("site.com/wp-content/themes/oaklandcentral/img/fb_logo.svg");
?>
Nothing is displaying. The actual link is correct and goes directly to the svg. Any thoughts?
Path is wrong, use file_get_contents( get_template_directory() . '/img/fb_logo.svg' )
echo file_get_contents("site.com/wp-content/themes/oaklandcentral/img/fb_logo.svg");
Assumptions:
your "filename" string starts with the protocol e.g. "http://"
that you can access the file directly from a browser (i.e. not a
file/folder permissions issue);
that file_get_contents is returning FALSE? (does the E_WARNING tell
you anything?)
I recollect seeing that some servers are not configured to allow file_get_contents (or readfile with URLs) so I would check investigate this first (maybe allow_url_fopen in php.ini???).
If this is not the case (or is a limitation by host provider) and you cannot find the cause of the problem then CURL should work (on most servers!).
$url = 'http://example.com/path-to/fb_logo.svg';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_REFERER, $_SERVER['REQUEST_URI']);
$svg = curl_exec($ch);
curl_close($ch);
echo $svg;
Edit:
It also appears you could also use php include if you remove the xml header tag from your SVG file.
I assume you want to display the SVG image not its text code, in which case why not simply <img src="<?php echo $mySvgFileUrl"; ?>"> like any other image?
Add header using: header("Content-Type: image/svg+xml"); before you echo the svg. sometimes the browser assumes the data received is html by default.
What could possibly be the problem.
The file isn't where you think it is.
File permission isn't allowing the code to read the file.
Try to debug:
<?php
$file = "site.com/wp-content/themes/oaklandcentral/img/fb_logo.svg";
if ( file_exists($file) ) {
echo file_get_contents($file);
} else {
echo "File $file does not exist";
}
?>
Try to get the page with curl. Take a look at the headers and the raw https response.
curl -v URL_TO_PAGE
Try:
<?php echo file_get_contents(get_template_directory().'/theme/img/chevron-right-solid.svg'); ?>
this seemed to work for me, where using get_template_directory_uri() did not (it threw an OpenSSL error)
Then, you can target the SVG and style how you wish.
For example:
<button class="btn btn-primary">
<?php echo file_get_contents(get_template_directory().'/theme/img/chevron-right-solid.svg'); ?>
</button>
CSS might be:
.btn svg { line-height: 1.2; max-height: 1rem;}
Try to use below code.
$opts = array(
'http'=>array(
'method'=>"GET",
'header'=>"Accept-language: en\r\n" .
"Cookie: foo=bar\r\n"
)
);
$context = stream_context_create($opts);
$file = file_get_contents('site.com/wp-content/themes/oaklandcentral/img/fb_logo.svg', false, $context);

Strange "JPEG datastream contains no image" with PHP

I am getting a remote image and checking the size of it.
Sometimes I get a strange error saying JPEG datastream contains no image and I narrowed it down that it's happening at this step, in fact it's happening EXACTLY at imagecreatefromstring. What could be the problem? An issue with the image? Or do I need to increase some kind of memory setting in php.ini or..?
function ranger($url) {
$headers = array(
"Range: bytes=0-32768"
);
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$data = curl_exec($curl);
curl_close($curl);
return $data;
}
$url = $prod['IMAGE1'];
$raw1 = ranger($url);
$im = imagecreatefromstring($raw1);
$width = imagesx($im);
$height = imagesy($im);
You need to follow these three steps to solve your problem:
As the error message clearly states, you do not have an image. You need to determine why you do not have an image. You could start by running var_dump($raw1) but you could take a look at the algorithm in general. After this step you should know why you do not have an image where you expected one.
?
User a valid image resource as a parameter of imagecreatefromstring.

Showing in a site images belonging to other domain using php

I have two domains sharing the same server. One of them, site_1.com, holding images at directory /images and the other one site, site_2.com, must to show those images. I have the following code at site_2:
<html>
<body>
<img src="http://site_1.com/images/img.png" />
</body>
</html>
Result: It didn't work. After reading a lot of answers and comment here and other forums I applied their sugges of using for example an api at site_1 like this:
/api/get_image.php at site_1.com:
<?php
$file_name = $_GET['file_name'];
$url = 'http://site_1.com/images/'.$file_name;
header('Content-type: image/png');
imagepng(imagecreatefrompng($url));
?>
And call the api at site_2.com like this:
<html>
<body>
<img src='http://site_1.com/api/get_image.php?file_name='img.png' />
</body>
</html>
It didn't work.
Another way using file_get_contens():
<?php
$file_name = $_GET['file_name'];
$url = 'http://site_1.com/images/'.$file_name;
$img = file_get_contents($url) ;
echo $img ;
?>
It didn't work.
Another way using CURL library:
<?php
$file_name = $_GET['file_name'];
$url = 'http://site_1.com/images/'.$file_name;
//
$ch = curl_init();
$timeout = 0;
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1);
$image = curl_exec($ch);
curl_close($ch);
echo $image ;
?>
It didn't work.
It's problably that I'm doing something wrong but I don't know what is. By the way, allow_url_fopen is ON and may be I have to active some other flag in some configuration file of apache or php. Please, could anybody tell me where is the problem? I appreciate any help.
sharing the same server.
Put images to some shared folder (i.e. both users for site_1 and site_2 can have access to it) and create symlinks to public folders of both sites
If you want to use your solution I think you should send appropriate header, e.g. header('Content-type: image/jpg');
header('Content-Type: image/'.$fileType);
readfile($filePath);

php Curl clicked links

I need any link that has a "a href=" tag when clicked to be received via curl. I can't hard code these links as they are from a dynamic site so could be anything. How would I achieve this?
Thanks
Edit: Let me explain more. I have an app on my pc that uses a web front end. It catalogs files and gives yo options to rename delete etc. I want to add a public view however if I put it as is online then anyone can delete rename files. If I curl the pages I can remove the menu bars and editing options through the use of a different css. That part all works. The only part that isn't working is if I click on a link on the page it directs me back to the original link address and that defeats the point as the menu bars are back. I need it to curl the clicked links. Hope that makes more sense..
Here is my code that fetches the original link and curls that and changes the css to point to my own css. It points the java script to the original as I dont need to change that. I now need to make the "a href" links on the page when clicked be called by curl and not go to the original destination
<?php
$ch = curl_init();
curl_setopt ($ch, CURLOPT_URL, 'http://192.168.0.14:8081/home/');
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
$curl_response = curl_exec($ch);
curl_close($ch);
//Change link url
$link = $curl_response;
$linkgo = '/sickbeard_public';
$linkfind = 'href="';
$linkreplace = 'href="' . $linkgo ;
$link = str_replace($linkfind, $linkreplace, $link);
//Change js url
$js = $link;
$jsgo = 'http://192.168.0.14:8081';
$jsfind = 'src="';
$jsreplace = 'src="' . $jsgo ;
$js = str_replace($jsfind, $jsreplace, $js);
//Fix on page link errors
$alink = $js;
$alinkgo = 'http://192.168.0.14:8081/';
$alinkfind = 'a href="/sickbeard_public/';
$alinkreplace = 'a href="' . $alinkgo ;
$alink = str_replace($alinkfind, $alinkreplace, $alink);
//Echo page back
echo $alink;
?>
You could grab all the URLs using a regular expression
// insert general warning about how parsing HTML using regex is evil :-)
preg_match('/href="([^"]+)"/', $html, $matches);
$urls = array_slice($matches, 1);
// Now just loop through the array and fetch the URLs with cUrl...
While I can't imagine why you would do that I think you should use ajax.
Attach an event on every a tag and send them to a script on your server where the magic of curl would happen.
Anyway you should explain why you need to fetch data with curl.
As far as I can understand your question you need to get the contents of URL via CURL... so here is the solution
Click here to get via curl
Then attach an event with the above <a> tag, e.g. in JQuery
$("#my_link").click(function(){
var target_url = $(this).attr("href");
//Send an ajax call to some of your page like cURL_wrapper.php with target_url as parameter in get
});
then in cURL_wrapper.php do follwoing
<?php
//Get the $target_url here from $_GET[];
$ch = curl_init($your_domain");
$fp = fopen("$target_url", "r");
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_exec($ch);
curl_close($ch);
fclose($fp);
?>

Get html cross site, display it and get an element value

I need to get the complete output from an aspx site. When the user leaves I will save what's in some specific elements in cookies. The problem is that the aspx is on a domain I don't have access to. I want the output to behave as in an iframe so links need to be clickable but it won't leave my page.
I think of either AJAX with PHP-proxy or an iframe that I can modify content in.
Is this possible?
If it is possible and it involves server-side code I would like to know if there are any free web hosts that support the full code( for example almost every free web host has safe_mode on for PHP).
EDIT: I want to display this page : School scheme. The URL doesn't to change, it just sends requests to the server (think via JavaScript). When the user leaves I will see what's in the select box id="TypeDropDownList" and what's in the select box id="ScheduleIDDropDownList".
When the user returns to my page I will print those values to the page via URL like this "http://www.novasoftware.se/webviewer/(S(lv1isca2txx1bu45c3kvic45))/design1.aspx?schoolid=27500&code=82820&type=" + type + "&id=" + id + "
I tried several php proxy scripts on 000webhost before I posted here.
for example this :
<?php
ob_start();
function logf($message) {
$fd = fopen('proxy.log', "a");
fwrite($fd, $message . "\n");
fclose($fd);
}
?>
<?
$url = $_REQUEST['url'];
logf($url);
$curl_handle = curl_init($url);
curl_setopt($curl_handle, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl_handle, CURLOPT_USERAGENT, "Owen's AJAX Proxy");
$content = curl_exec($curl_handle);
$content_type = curl_getinfo($curl_handle, CURLINFO_CONTENT_TYPE);
curl_close($curl_handle);
header("Content-Type: $content_type");
echo $content;
ob_flush();
?>
But it returns Warning: curl_setopt(): supplied argument is not a valid cURL handle resource in /home/a5379897/public_html/ajax-proxy.php on line 16
I tried to contact them about this because they say they have cURL enabled but they haven't responded yet.
I think it would be possible to just display the two select boxes when the user first visit the page. When options is selected it will make an iframe show the right page by passing "http://www.novasoftware.se/webviewer/(S(lv1isca2txx1bu45c3kvic45))/design1.aspx?schoolid=27500&code=82820&type=" + type + "&id=" + id + " to the src attribute.
The problem with that is that I will need to retrieve the select boxes someway and I will have the same problem.
You would need to use PHP as Javascript doesn't doesn't allow cross domain requests. Your PHP code would literally grab the page the client wants, process it (changing link's href to your page with a get variable of the page the original href links to). When they click the link they will be sent to the same page they are on now but the page will grab the new page and return that(processing that page too) and so on.
000webhost are a nice free webhost that allow you to do most of PHP's functions and don't put adverts on your site.
To get the whole aspx output as a string to manipulate, you can use file_get_contents(http://yoursite.com/yourpage.aspx);
For best results, open a stream as the context via http.
<?php
// Create a stream
$opts = array(
'http'=>array(
'method'=>"GET",
'header'=>"Accept-language: en\r\n" .
"Cookie: foo=bar\r\n"
)
);
$context = stream_context_create($opts);
// Open the file using the HTTP headers set above
$file = file_get_contents('http://www.example.com/', false, $context);
?>
Thanks to greg I could create this script that gets the page.
<html>
<head>
</head>
<body>
<?php
// Create a stream
$opts = array(
'http'=>array(
'method'=>"GET",
'header'=>"Accept-language: en\r\n" .
"Cookie: foo=bar\r\n"
)
);
$context = stream_context_create($opts);
$host = 'http://www.novasoftware.se/webviewer/(S(bkjwdqntqzife4251x4sdx45))/';
$url = '/design1.aspx?schoolid=27500&code=82820&type=3&id={7294F285-A5CB-47D6-B268-E950CA205560}';
$changetothis='src="'.$host;
// Open the file using the HTTP headers set above
$file = file_get_contents($host.$url, false, $context);
$changed = str_replace('src="', $changetothis,$file);
echo $changed;
?>
</body>
</html>

Categories