How to handle get_headers() function if URL doesn't exist - php

While usign the function get_headers() for example, If i wrote
get_headers("www.websitedoesntexist.com");
i get the following error
Warning: get_headers(): php_network_getaddresses: getaddrinfo failed:
No such host is known Warning:
get_headers(www.websitedoesntexist.com): failed to open stream:
php_network_getaddresses: getaddrinfo failed: No such host is known
I want to know how to handle these problems, Something like
if (isset(get_headers("www.websitedoesntexist.com"))) {
echo "URL Exists";
}

Suppress errors on the get_headers() function. Assign get_headers to a variable. Then check the Boolean value of that variable.
$file_headers = #get_headers("www.websitedoesntexist.com");
if(!$file_headers) {
$exists = false;
}
else {
$exists = true;
}
Edit:
Based on the comments, for a better, long-term solution using curl see https://stackoverflow.com/a/36743670/4374801

From the PHP manual :
Returns an indexed or associative array with the headers, or FALSE on failure.
Which means you can test against FALSE.
Read more : http://php.net/manual/en/function.get-headers.php
Edit
If you want just to check if the URL exists or not, instead of supressing the errors I suggest you use curl, a simple function like this can do the job :
function url_exists($url) {
if (!$fp = curl_init($url)) {
return false;
}
return true;
}

if you want to check the url exist or not in php, simply code this.testing purpose
$array = get_headers('url');
$string = $array[0];
if (strpos($string, "200")) {
echo "thats cool dude";
} else {
echo "Bad request";
}

Related

Automatic conversion of false to array is deprecated

I get this warning in a chunk of instructions PHP 8+ dedicated to the check of the user inside the page:
if ($_POST['go'] ?? null) {
// $_SESSION_VALUES is an array $db, $nick are classes of mine
$_SESSION_VALUES = $nick->get_cookie (COOKIE_NAME); // get the name of the cookie
if ($db->check_user (USERS_TABLE, $_POST['nick'], $db->encode_password($_POST['password']))) {
$_SESSION_VALUES['_USERNAME'] = $db->user_rec['nick']; // get the nickname from the cookie
$_SESSION_VALUES['_PASSWORD'] = $db->user_rec['password']; //get the password
$_SESSION_VALUES['_USER'] = $db->user_type;
if (! $nick->set_cookie (COOKIE_NAME, $_SESSION_VALUES)) die ('Cannot write the cookie'); // record the cookie
header('Location: ./copertina'); }
else $_SESSION_VALUES['_USER'] = -1;
}
The execution of
else $_SESSION_VALUES['_USER'] = -1;
gives "Automatic conversion of false to array is deprecated"
Following a suggestion from stack overflow I tryed this:
$\_SESSION_VALUES = \[\];
if ($\_POST\['go'\] ?? null) {
...
but apparently it doesn't work
any idea?
Thanks
I assume that $nick->get_cookie(COOKIE_NAME); returns false.
Try changing:
else $_SESSION_VALUES['_USER'] = -1;
to:
else $_SESSION_VALUES = ['_USER' => -1];
This will probably get rid of the error message you reported, but I don't know if the rest of your code, which I cannot see, will accept this.

How do you run an api call through a try/catch to ensure connection is working?

I have an api call that I want to run through a try/catch statement.
I have tried both ‘try/catch’ and an ‘if/else’ to check to see if the api call can be made.
When internet is disconnected both methods crash and call an error,
file_get_contents(): php_network_getaddresses: getaddrinfo failed: nodename nor servname provided, or not known
1 method)
try {
$json = json_decode(file_get_contents('https://api.coinmarketcap.com/v1/ticker/bitcoin/'), true);
$BTCprice=$json["0"]["price_usd"];
} catch (Exception $e) {
$BTCprice = 0;
}
2 method)
if ( file_get_contents('https://api.coinmarketcap.com/v1/ticker/bitcoin/') ) {
$json = json_decode(file_get_contents('https://api.coinmarketcap.com/v1/ticker/bitcoin/'), true);
$BTCprice=$json["0"]["price_usd"];
} else {
$BTCprice = 0;
}
How do you run an api call through a try/catch to ensure connection is working?
file_get_contents() does not throw exceptions, only returning false on failure. http://php.net/manual/en/function.file-get-contents.php
So, that said, option 2 is the way to do it. However, I would tweak it, because you make the request TWICE.
<?php
$BTCprice = 0;
if ($data = file_get_contents('https://api.coinmarketcap.com/v1/ticker/bitcoin/') ) {
$json = json_decode($data, true);
$BTCprice = $json["0"]["price_usd"];
}
You can check it like this
if($json === FALSE) {
$BTCprice = 0;
} else {
//your thing
}
if you want to ignore the error msg you can also use php error control operator

Warning: implode(): Invalid arguments passed at load page

My script load a title of url when this load by php_self in a html form.
<?php
$bk_url=$_REQUEST['bk_url'];
$remote_url = $bk_url;
$from_remote_url = implode("", file("".$remote_url));
if(preg_match("/<title>(.+)<\/title>/", $from_remote_url, $regs)) {
} else {
echo "<br> Title empty. Manual insert";
}
?>
When load the php page, are displayed two errors:
Warning: file(http://): failed to open stream: operation failed
and this error:
Warning: implode(): Invalid arguments passed
I have try to find a solution on stackoverflow but not find any solution.
How to fix this two errors?
Thanks
You need to run the code only when the user has submitted the form. So check first to see if the variable is set.
if (isset($_REQUEST['bk_url'])) {
$bk_url=$_REQUEST['bk_url'];
$remote_url = $bk_url;
$from_remote_url = implode("", file("".$remote_url));
if(preg_match("/<title>(.+)<\/title>/", $from_remote_url, $regs)) {
} else {
echo "<br> Title empty. Manual insert";
}
}

PHP imap_reopen no error returned

I have a script that connects to a mailbox.
I'd like to check if I can connect to a folder that does not exist, but imap_reopen does not return errors.
<?php
$imap_url = "{mybox.mail.box:143}";
$mbox = imap_open($imap_url, "Mylogin", "Mypassword");
if ($mbox == false) {
echo "Opening mailbox failed\n";
}
$submbox = imap_listmailbox($mbox, $imap_url, "*");
if ($submbox == false) {
echo "Listing sub-mailboxes failed\n";
}
else {
foreach ($submbox as $name) {
echo $name . PHP_EOL;
}
}
$test = imap_reopen($mbox, $imap_url . "INBOX.MBOX3") or die(implode(", ", imap_errors()));
if ($test == false) {
echo "Opening submbox failed\n";
}
?>
Script output :
{mybox.mail.box:143}.INBOX
{mybox.mail.box:143}.INBOX.MBOX1
{mybox.mail.box:143}.INBOX.MBOX2
PHP Notice: Unknown: Mailbox does not exist (errflg=2) in Unknown on line 0
Do you have an idea ?
Regards,
Stiti
Your statement ending with or die() is actually terminating execution before the if test against the return value in $test.
$test = imap_reopen($mbox, $imap_url . "INBOX.MBOX3") or die(implode(", ", imap_errors()));
// This code is never reached because of die()!
if ($test == false) {
echo "Opening submbox failed\n";
}
So just remove the or die() expression and your if ($test == false) will be evaluated. I'll also use === here since it should return a true boolean:
// Call imap_reopen() without (or die())
$test = imap_reopen($mbox, $imap_url . "INBOX.MBOX3");
if ($test === false) {
echo "Opening submbox failed\n";
}
You may alternatively use
if (!$test) {
echo "Opening submbox failed\n";
}
Note about the PHP E_NOTICE emitted - if imap_reopen() emits that notice even when returning false, this is one instance in which you may want to use the # operator for error suppression since you are correctly testing for errors in your if block.
// # is not usually recommended but if imap_reopen()
// prints an E_NOTICE while still returning false you can
// suppress it with #. This is among the only times it's
// a good idea to use # for error suppresssion
$test = #imap_reopen($mbox, $imap_url . "INBOX.MBOX3");
if (!$test) {...}
Addendum after testing:
Documentation on imap_reopen() is slim and ambiguous stating its return as:
Returns TRUE if the stream is reopened, FALSE otherwise.
Some testing seems to imply that opening a non-existent mailbox is not considered an error state for which it returns false. When opening a non-existent mailbox on an otherwise valid stream, imap_reopen() will still return true but populate an error in imap_errors().
So you may check count(imap_errors()) > 0 for errors after opening the faulty mailbox. Couple that with a true return check, in case imap_reopen() does return a true error state.
For example my testing produces results similar to:
$test = imap_reopen($mbox, $imap_url . "NOTEXIST");
var_dump($test);
// bool(true);
var_dump(imap_errors()); array(1) {
[0] =>
string(28) "Mailbox doesn't exist: NOTEXIST"
}
You may work around this using logic to:
$test = #imap_reopen($mbox, $imap_url . "INBOX.MBOX3");
if (!$test) {
// An error with the stream
}
// Returns true, but imap_errors() is populated
else if ($test && count(imap_errors()) > 0) {
echo "Opening submbox failed\n";
// Do something with imap_errors() if needed
echo implode(',', imap_errors());
}
else {
// Everything is fine - the mailbox was opened
}
For what it's worth, imap_open() exhibits the same behavior. Successfully connecting and establishing the stream (your variable $mbox) is possible with a non-existent mailbox. The stream is created and valid, but imap_errors() will contain a message Mailbox doesn't exist: <mailbox>.

Handle error when getimagesize can't find a file

when I'm trying to getimagesize($img) and the image doesn't exist, I get an error. I don't want to first check whether the file exists, just handle the error.
I'm not sure how try catch works, but I want to do something like:
try: getimagesize($img) $works = true
catch: $works = flase
Like you said, if used on a non-existing file, getimagesize generates a warning :
This code :
if ($data = getimagesize('not-existing.png')) {
echo "OK";
} else {
echo "NOT OK";
}
will get you a
Warning: getimagesize(not-existing.png) [function.getimagesize]:
failed to open stream: No such file or directory
A solution would be to use the # operator, to mask that error :
if ($data = #getimagesize('not-existing.png')) {
echo "OK";
} else {
echo "NOT OK";
}
As the file doesn't exist, $data will still be false ; but no warning will be displayed.
Another solution would be to check if the file exists, before using getimagesize ; something like this would do :
if (file_exists('not-existing.png') &&
($data = getimagesize('not-existing.png'))
) {
echo "OK";
} else {
echo "NOT OK";
}
If the file doesn't exist, getimagesize is not called -- which means no warning
Still, this solution is not the one you should use for images that are on another server, and accessed via HTTP (if you are in this case), as it'll mean two requests to the remote server.
For local images, that would be quite OK, I suppose ; only problem I see is the notice generated when there is a read error not being masked.
Finally :
I would allow errors to be displayed on your developpement server,
And would not display those on your production server -- see display_errors, about that ;-)
Call me a dirty hacker zombie who will be going to hell, but I usually get around this problem by catching the warning output into an output buffer, and then checking the buffer. Try this:
ob_start();
$data = getimagesize('not-existing.png');
$resize_warning = ob_get_clean();
if(!empty($resize_warning)) {
print "NOT OK";
# We could even print out the warning here, just as PHP would do
print "$resize_warning";
} else {
print "OK"
}
Like I said, not the way to get a cozy place in programmer's heaven, but when it comes to dysfunctional error handling, a man has to do what a man has to do.
I'm sorry that raise such old topic. Recently encountered a similar problem and found this topic instead a solution. For religious reasons I think that '#' is bad decision. And then I found another solution, it looks something like this:
function exception_error_handler( $errno, $errstr, $errfile, $errline ) {
throw new Exception($errstr);
}
set_error_handler("exception_error_handler");
try {
$imageinfo = getimagesize($image_url);
} catch (Exception $e) {
$imageinfo = false;
}
This solution has worked for me.
try {
if (url_exists ($photoUrl) && is_array (getimagesize ($photoUrl)))
{
return $photoUrl;
}
} catch (\Exception $e) { return ''; }
Simple and working solution based on other answers:
$img_url = "not-existing.jpg";
if ( is_file($img_url) && is_array($img_size = getimagesize($img_url)) ) {
print_r($img_size);
echo "OK";
} else {
echo "NOT OK";
}

Categories