how to know if a certain resource exist? - php

For instance, I want to know if these files exists.
http://www.stackoverflow.com/favicon.ico
http://www.stackoverflow.com/reset.css
and then download it ( if exixts obviously ).

<?php
if( ( $file = file_get_contents( 'http://www.stackoverflow.com/favicon.ico' ) ) ) {
echo "file exists.";
file_put_contents( 'favicon.ico', $file );
}
else {
echo "File does not exist.";
}

Try this:
<?php
$ch = curl_init();
$url = 'YOUR_URL_HERE'; // the url you want to check
curl_setopt( $ch, CURLOPT_URL, $url );
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1 );
curl_setopt( $ch, CURLOPT_CONNECTTIMEOUT, 20 );
curl_setopt( $ch, CURLOPT_USERAGENT, $_SERVER[ 'HTTP_USER_AGENT' ] );
// make "HEAD" request
curl_setopt( $ch, CURLOPT_HEADER, true );
curl_setopt( $ch, CURLOPT_NOBODY, true );
$res = curl_exec( $ch );
$res = explode( ' ', substr( $res, 0, strpos( $res, "\n" ) ) );
// if 404, file does not exist
if( $res[ 1 ] != 404 ) {
$file = file_get_contents( $url );
} else {
// This url does not exist
$file = '';
}
curl_close( $ch );
?>
Hope this helps.

Related

fetch X-WP-Total and X-WP-TotalPages response headers using php curl request

I'm trying to read the X-WP-* headers using a curl response requested on the WordPress API for fetching posts (See reference:https://developer.wordpress.org/rest-api/using-the-rest-api/pagination/) e.g https://news.harvard.edu/wp-json/wp/v2/posts.
however I'm unable to read the http response headers returned.
$url = "https://news.harvard.edu/wp-json/wp/v2/posts";
$headers = [];
$data=[];
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT ,0);
curl_setopt($curl, CURLOPT_TIMEOUT, 0);
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HEADER, true);
curl_setopt($curl, CURLOPT_HEADERFUNCTION,
function ($curl, $header) use (&$headers) {
$len = strlen($header);
$header = explode(':', $header, 2);
if (count($header) < 2) // ignore invalid headers
return $len;
$headers[strtolower(trim($header[0]))][] = trim($header[1]);
return $len;
}
);
$response = curl_exec($curl);
if ($response == false) {
if(curl_errno($curl)>=1){
$error = curl_errno($curl);
curl_close($curl);
$data = ["curl_error"=>$error];
}
}else{
$data = [
"headers"=>$headers
];
curl_close($curl);
}
var_dump($data);
// $data doesn't contain X-WP-Total and X-WP-TotalPages
You were nearly there with the above but it lacks any SSL support which is why I believe it was failing. If you set the CURLOPT_HEADER=true option (as above) this code will still work but you'll not be able to decode the JSON response - you do not need to actually print the headers so set this as false or omit completely.
$url = "https://news.harvard.edu/wp-json/wp/v2/posts";
$cacert='c:/wwwroot/cacert.pem';
/*
Download a copy of CACERT.pem from
https://curl.haxx.se/docs/caextract.html
save to webserver and modify the $cacert variable
to suit - ensuring that the path you choose is
readable.
*/
$headers = [];
$data=[];
# slightly modified version of original function
# only appends matching headers to output variable.
$callback=function( $ch, $header ){
global $headers;
$len = strlen( $header );
$header = explode(':', $header, 2 );
if( count( $header ) < 2 ) return $len;
$param = strtolower( trim( $header[0] ) );
$value = trim( $header[1] );
if( strstr( $param, 'x-wp' ) ) $headers[ $param ]=$value;
return $len;
};
$curl=curl_init();
# The request will fail without including options for dealing with SSL.
if( parse_url( $url, PHP_URL_SCHEME )=='https' ){
curl_setopt( $curl, CURLOPT_SSL_VERIFYPEER, true );
curl_setopt( $curl, CURLOPT_SSL_VERIFYHOST, 2 );
curl_setopt( $curl, CURLOPT_CAINFO, $cacert );
}
curl_setopt( $curl, CURLOPT_URL, trim( $url ) );
curl_setopt( $curl, CURLOPT_CONNECTTIMEOUT ,0 );
curl_setopt( $curl, CURLOPT_TIMEOUT, 0 );
curl_setopt( $curl, CURLOPT_RETURNTRANSFER, true );
# we do not need the header in the output
curl_setopt( $curl, CURLOPT_HEADER, false );
# but we do need to process request headers - find any X-WP* headers
curl_setopt( $curl, CURLOPT_HEADERFUNCTION, $callback );
$res = curl_exec($curl);
curl_close( $curl );
# process the required headers...
printf( '<pre>%s</pre>', print_r( $headers, true ) );
$json=json_decode( $res );
# do stuff with JSON data
This outputs the following:
Array
(
[x-wp-total] => 25118
[x-wp-totalpages] => 2512
)

POST request returns empty when called by 3rd app but not when called manually

I have an app in adalo.com which calls my custom api (simple PHP file) api.domain.com. When it is called, there are two requests to jotform.com.
First is GET and works nicely. And second is POST.
When I tried the POST request on localhost with custom data, it works. It also work when I try POST request via https://reqbin.com/.
So the problem is, as it seems, when Adalo app calls my API after I submit form.
Everything works just not the POST request (e.g. I got all data from Adalo form in the log file and GET request to Jotform works).
Below the code of function.
function post_data( $path, $post_data = array() ) {
if( empty( $path ) || empty( $post_data ) ) return false;
$api_url = JOTFORM_API_URL;
$api_key = JOTFORM_API_KEY;
$post_data_url = implode( '&', $post_data );
// error_log( 'post_data' );
// error_log( $post_data_url );
$url = "{$api_url}{$path}?apikey={$api_key}&{$post_data_url}";
// error_log( 'url' );
// error_log( $url );
// echo $url . "\n\n";
// return;
$curl = curl_init();
curl_setopt( $curl, CURLOPT_URL, $url );
curl_setopt( $curl, CURLOPT_RETURNTRANSFER, 1 );
curl_setopt( $curl, CURLOPT_USERAGENT, 'JOTFORM_PHP_WRAPPER');
curl_setopt( $curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt( $curl, CURLOPT_POST, true);
$exec = curl_exec( $curl );
if ( $exec === false ) {
error_log( curl_error( $curl ) );
}
$data = json_decode( $exec, true );
curl_close( $curl );
error_log( var_dump( $data ) );
return $data;
}

PHP's fopen() can't get url, but curl can

A while back, I wrote a little utility function that takes inPath and outPath, opens both and copies from one to the other using fread() and fwrite(). allow_url_fopen is enabled.
Well, I've got a url that I'm trying to get the contents of, and fopen() doesn't get any data, but if I use curl to do the same, it works.
The url in question is: http://www.deltagroup.com/Feeds/images.php?lid=116582497&id=1
fopen version:
$in = #fopen( $inPath, "rb" );
$out = #fopen( $outPath, "wb" );
if( !$in || !$out )
{
echo 0;
}
while( $chunk = fread( $in, 8192 ) )
{
fwrite( $out, $chunk, 8192 );
}
fclose( $in );
fclose( $out );
if( file_exists($outPath) )
{
echo 1;
}
else
{
echo 0;
}
curl version:
$opt = "curl -o " . $outPath . " " . $inPath;
$res = `$opt`;
if( file_exists($outPath) )
{
echo 1;
}
else
{
echo 0;
}
Any idea why this would happen?
Even using php's curl, I was unable to download the file- until I added a curlopt_useragent string. Nothing in the response indicated that it was required (no errors, nothing other than an HTTP 200).
Final code:
$out = #fopen( $outPath, "wb" );
if( !$out )
{
echo 0;
}
$ch = curl_init();
curl_setopt( $ch, CURLOPT_URL, $inPath );
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt( $ch, CURLOPT_FILE, $out );
curl_setopt( $ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows; U; Windows NT 6.1; en; rv:1.9.2.13) Gecko/20101203 Firefox/3.6.13');
curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, true );
curl_setopt( $ch, CURLOPT_CONNECTTIMEOUT, 15 );
curl_setopt( $ch, CURLOPT_TIMEOUT, 18000 );
$data = curl_exec( $ch );
curl_close( $ch );
fclose( $out );
if( file_exists($outPath) )
{
echo 1;
}
else
{
echo 0;
}

What is going wrong with this API?

I am coding a website for my friend whom plays Habbo Hotel which is a virtual game. He linked me to some API.
http://habboemotion.com/guide/habinfo & http://habboemotion.com/guide/habboapi
I have been using this code to show the data from the api.
<?php
$info = habbo( "Tyler", "com" );
if( $info ) {
foreach( $info->user AS $name ) {
echo $name->motto;
}
} else {
echo "Habbo not found";
}
?>
Why is nothing appearing? It just appears to be a blank screen.
As the previous person said, make sure to include your habbo() function.
I changed the habbo() function to remove gzip compression and gzinflate(). That seemed to fix the blank page issue. However it seems to take a few seconds to load the page and is on the slow side.
It would also appear that $user->motto isn't allowed. As such, I've replaced it with $friends->motto.
Hope this helps! I am still very new to APIs.
<?php
error_reporting(E_ALL); // Debugging
ini_set('display_errors', 1); // Debugging
function habbo( $name, $hotel ) {
$ch = curl_init();
curl_setopt( $ch, CURLOPT_URL, "https://www.habbo." . $hotel . "/api/public/users" );
curl_setopt( $ch, CURLOPT_HEADER, false );
curl_setopt( $ch, CURLOPT_HTTPHEADER, array( 'Accept-Encoding: identity' ) ); // Changed to "identity"
curl_setopt( $ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT'] );
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, true );
curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, 0 );
curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, 0 );
$response = curl_exec( $ch ); // Added
//$get = gzinflate( substr( curl_exec( $ch ), 10, -8 ) );
//preg_match( "/setCookie\((.*)\);/", $get, $get );
//$get = explode( ",", str_replace( array( "'", " " ), "", $get[1] ) );
//curl_setopt( $ch, CURLOPT_HTTPHEADER, array( "Cookie:" . $get[0] . "=" . $get[1] ) );
curl_setopt( $ch, CURLOPT_URL, "http://www.habbo." . $hotel . "/api/public/users?name=" . $name );
$id = json_decode( curl_exec( $ch ) );
if( isset( $id ) && $id->profileVisible == 1 ) {
curl_setopt( $ch, CURLOPT_URL, "http://www.habbo." . $hotel . "/api/public/users/" . $id->uniqueId . "/profile" );
$info = json_decode( curl_exec( $ch ) );
} else
$info = false;
curl_close( $ch );
return $info;
}
Here is the function call:
$info = habbo( "Tyler", "com" );
if( $info ) {
foreach( $info->friends AS $friend ) {
echo $friend->motto . "<br />";
}
} else {
echo "habbo not found or homepage hidden";
}
?>

Fastest way to trigger a script on a page from PHP using cURL, don't wait for a response

Right now I am using cURL and something like that:
foreach ($urls as $url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url );
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_exec($ch);
}
to trigger a php script on a remote server.
My thing is I just want to trigger that script and doesn't care at all what it returns and I want to trigger another address that is in my loop.
So, how can I eliminate waiting for the response and just trigger the scripts on the servers (I have about 200 urls in my array I need to loop through and trigger each of these urls).
So, basically I want just to trigger the script and move to the next one and don't care what it returns.
And another concern of mine is that if I can move the curl_init() outside of the loop like that:
$ch = curl_init();
foreach ($urls as $url) {
curl_setopt($ch, CURLOPT_URL, $url );
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_exec($ch);
}
If there is a faster way how to achieve this without using cURL, please let me know.
I just need to trigger 100 scripts on remote servers from one loop inside one file.
<?php
$fp = fsockopen("mesela.dom", 80, $errno, $errstr, 30);
if (!$fp) {
    echo "$errstr ($errno)<br />\n";
} else {
    $out = "GET / HTTP/1.1\r\n";
    $out .= "Host: mesela.dom\r\n";
    $out .= "Connection: Close\r\n\r\n";
    fwrite($fp, $out);
    fclose($fp);
}
?>
You can use a queue system with your code adding these URLs to be called as jobs and multiple workers doing the CURL calls.
This will make your code asynchronous ( not wait for response from the curl call).
A good PHP library you can use
https://github.com/chrisboulton/php-resque
curl multi
<?php
function setcurloptions( $handle=false, $url=false, $cacert=false ){
if( $handle && $url ){
if( parse_url( $url, PHP_URL_SCHEME )=='https' ){
curl_setopt( $handle, CURLOPT_SSL_VERIFYPEER, FALSE );
curl_setopt( $handle, CURLOPT_SSL_VERIFYHOST, 2 );
curl_setopt( $handle, CURLOPT_CAINFO, realpath( $cacert ) );
}
curl_setopt( $handle, CURLOPT_URL, $url );
curl_setopt( $handle, CURLOPT_HEADER, false );
curl_setopt( $handle, CURLOPT_FRESH_CONNECT, true );
curl_setopt( $handle, CURLOPT_FORBID_REUSE, true );
curl_setopt( $handle, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1 );
curl_setopt( $handle, CURLOPT_CLOSEPOLICY, CURLCLOSEPOLICY_OLDEST );
curl_setopt( $handle, CURLOPT_BINARYTRANSFER, true );
curl_setopt( $handle, CURLOPT_AUTOREFERER, true );
curl_setopt( $handle, CURLOPT_CONNECTTIMEOUT, 30 );
curl_setopt( $handle, CURLOPT_RETURNTRANSFER, true );
curl_setopt( $handle, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT'] );
}
}
$cacert='c:/wwwroot/cacert.pem';
$urls=array(
'http://www.example.com',
'http://www.example.com',
'http://www.example.com'
);
$multi = curl_multi_init();
$handles = array();
foreach( $urls as $i => $url ){
$handle = curl_init();
setcurloptions( $handle, $url, $cacert );
curl_multi_add_handle( $multi, $handle );
$handles[]=$handle;
}
$active=null;
do {
$mrc = curl_multi_exec( $multi, $active );
usleep(100);
} while( $mrc == CURLM_CALL_MULTI_PERFORM );
while( $active && $mrc == CURLM_OK ) {
if( curl_multi_select( $multi ) != -1 ) {
do {
$mrc = curl_multi_exec( $multi, $active );
} while( $mrc == CURLM_CALL_MULTI_PERFORM );
}
usleep( 100 );
}
foreach( $handles as $i => $handle ){
/*
if you want to do something at all with response
$response=curl_multi_getcontent( $handle );
*/
curl_multi_remove_handle( $multi, $handle );
curl_close( $handle );
usleep(100);
}
curl_multi_close( $multi );
?>

Categories