I have this code:
<?php
$url = "http://asdsfsfsfsfsdfad.com";
$file = file_get_contents($url);
if(preg_match("/<title>(.+)<\/title>/i",$file,$m))
print "$m[1]";
else
print "The page doesn't have a title tag";
?>
It works fine when the url is a proper url, but when I put in nonsense then I get two warning messages:
Warning: file_get_contents() [function.file-get-contents]: php_network_getaddresses: getaddrinfo failed: Navn eller tjeneste ukendt in /var/www/web17/web/administration/custom_pages.php(71) : eval()'d code on line 4
Warning: file_get_contents(http://asdsfsfsfsfsdfad.com) [function.file-get-contents]: failed to open stream: php_network_getaddresses: getaddrinfo failed: Navn eller tjeneste ukendt in /var/www/web17/web/administration/custom_pages.php(71) : eval()'d code on line 4
Any way to prevent this?
The easiest solution would be to just suppress the error:
echo #file_get_contents("http://asdsfsfsfsfsdfad.com");
However, error suppression is generally considered bad practise because you never know what went wrong, so it is better to have a handler that selectively handles errors, for instance
set_error_handler(function($code, $message) {
return ($code === E_WARNING && strpos($message, 'php_network_getaddresses'));
});
echo file_get_contents("http://asdsfsfsfsfsdfad.com");
This would suppress any E_WARNINGS with a message containing 'php_network_getaddresses'. Any other Warnings will not be suppressed.
In addition, you dont want Regex to parse HTML, but use an HTML Parser, like one of those given in
How do you parse and process HTML/XML in PHP?
So you could do it with DOM. Again, either using Error Suppression (bad)
$dom = new DOMDocument;
#$dom->loadHTMLFile("http://asdsfsfsfsfsdfad.com");
$titles = $dom->getElementsByTagName('title');
echo $titles->length ? $dom->nodeValue : 'No Title found';
Or selectively suppressing network errors:
set_error_handler(function($code, $message) {
return ($code === E_WARNING && strpos($message, 'php_network_getaddresses'));
});
$dom = new DOMDocument;
$dom->loadHTMLFile("http://asdsfsfsfsfsdfad.com");
$titles = $dom->getElementsByTagName('title');
echo $titles->length ? $titles->item(0)->nodeValue : 'No Title found';
However, this will then result in parsing errors because loadHTMLFile will not return any HTML, so to suppress the parsing errors as well, you'd have to do:
set_error_handler(function($code, $message) {
return ($code === E_WARNING && strpos($message, 'php_network_getaddresses'));
});
libxml_use_internal_errors(true);
$dom = new DOMDocument;
$dom->loadHTMLFile("http://asdsfsfsfsfsdfad.com");
libxml_clear_errors();
$titles = $dom->getElementsByTagName('title');
echo $titles->length ? $titles->item(0)->nodeValue : 'No Title found';
implode() expects the second parmeter to be an array, thus, check if $file is an array before doing an implode.
$file = is_array($file) ? implode("",$file) : $file;
Or even better, use file_get_contents, then you won't need to use implode:
$url = "http://asdsfsfsfsfsdfad.com";
$file = file_get_contents($url);
You should check the $file value for false before joining:
$url = "http://asdsfsfsfsfsdfad.com";
$file = file($url);
if ($file !== false) {
$file = implode("",$file);
if(preg_match("/<title>(.+)<\/title>/i",$file,$m)) {
print "$m[1]";
} else {
print "The page doesn't have a title tag";
}
} else {
print "wrong url";
}
you can check whether $file is array or not ..
if you check it then it will never give you an error..
if(is_array($file) && count($file)>0){
if(preg_match("/<title>(.+)<\/title>/i",$file,$m))
print "$m[1]";
else
print "The page doesn't have a title tag";
}
else{
echo "$file is not arrya so it does not go in the fi block.";
}
You don't need to add the quotes around the file contents string. When you use the function file_get_contents, it already returns the results as a string. By adding those double quotes around it, you are basically adding nothing to the string.
You can use curl to check if the url is valid:
<?
function url_exists($strURL) {
$resURL = curl_init();
curl_setopt($resURL, CURLOPT_URL, $strURL);
curl_setopt($resURL, CURLOPT_BINARYTRANSFER, 1);
curl_setopt($resURL, CURLOPT_HEADERFUNCTION, 'curlHeaderCallback');
curl_setopt($resURL, CURLOPT_FAILONERROR, 1);
curl_exec ($resURL);
$intReturnCode = curl_getinfo($resURL, CURLINFO_HTTP_CODE);
curl_close ($resURL);
if ($intReturnCode != 200 && $intReturnCode != 302 && $intReturnCode != 304) {
return false;
}Else{
return true ;
}
}
//Usage Example :
If(url_exists("http://www.weberdev.com/addexample.php3")) {
Echo"URL Exists";
}Else{
Echo"URL doesnot exist";
}
?>
See http://www.weberdev.com/get_example.php3?ExampleID=4335 for more information.
Related
I would like to use the following to detect if a file exists, however there is a warning triggered when when this is the case. It works fine when file_get_contents does not return false.
$nothing = "http://www.google.com/bababababa.doc";
if (false === file_get_contents($nothing,0,null,0,1)) {
echo "File Not Found";
} else {
echo "File Found";
}
First, I'll assume that you only want to hide this error from your logs, because of course you have display_errors turned off on a production server.
You could just hide your errors away with the # error suppression operator, but that's a bad road to start down. Instead you want to define an error handler:
<?php
// define the custom handler that just returns true for everything
$handler = function ($err, $msg, $file, $line, $ctx) {return true;}
$nothing = "http://www.google.com/bababababa.doc";
// update the error handler for warnings, keep the old value for later
$old_handler = set_error_handler($handler, E_WARNING);
// run the code
$result = file_get_contents($nothing);
// go back to normal error handling
set_error_handler($old_handler);
if (false === $result) {
echo "File Not Found";
} else {
echo "File Found";
}
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>.
$xml = $_GET['url']
$xmlDoc = new DOMDocument();
$xmlDoc->load($xml);
..
..
if the user put without http or https my script will be broken, is concatenation a good way to validation in this case?
The simplest way of doing this is checking for the presence of http:// or https:// at the beginning of the string.
if (preg_match('/^http(s)?:\/\//', $xml, $matches) === 1) {
if ($matches[1] === 's') {
// it's https
} else {
// it's http
}
} else {
// there is neither http nor https at the beginning
}
You are using a get method. Or this is done by AJAX, or the user appends a url in the querystring You are not posting a form?
Concatenation isn't going to cut it, when the url is faulty. You need to check for this.
You can put an input with placeholder on the page, to "force" the user to use http://. This should be the way to go in HTML5.
<input type="text" pattern="^(https?:\/\/)([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$" placeholder="http://" title="URLs need to be proceeded by http:// or https://" >
This should check and forgive some errors. If an url isn't up to spec this will return an error, as it should. The user should revise his url.
$xml = $_GET['url']
$xmlDoc = new DOMDocument();
if (!preg_match(/^(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$/, $xml ) )
{
echo 'This url is not valid.';
exit;
}
else if (!preg_match(/^http(s)?:\/\/, $xml))
{
//no http present
$orgUrl = $xml;
$xml = "http://".$orgUrl;
//extended to cope with https://
$loaded = loadXML();
if (substr($loaded, 0, 5) == "false")
{
//this attempt failed.
$xml = "https://".$orgUrl;
$loaded = loadXML();
if (substr($loaded, 0, 5) == "false")
{
echo substr($loaded, 6);
exit;
}
}
}
else
{
$loaded = loadXML();
}
function loadXML()
{
try {
return $xmlDoc->load($xml);
}
catch($Ex)
{
return echo 'false Your url could\'t be retrieved. Are you sure you\'ve entered it correctly?';
}
}
You can also use curl to check the url before loading xml:
$ch = curl_init($xml);
// Send request
curl_exec($ch);
// Check for errors and display the error message
if($errno = curl_errno($ch)) {
$error_message = curl_strerror($errno);
echo "$error_message :: while loading url";
}
// Close the handle
curl_close($ch);
Important side-note: Using this methods to check if the url is available and than take the appropriate action can take a very long time, since the server response can take a while to return.
so I'm grabbing some information from an XML file like so:
$url = "http://myurl.blah";
$xml = simplexml_load_file($url);
Except sometimes the XML file is empty and I need the code to fail gracefully but I can't seem to figure out how to catch the PHP error. I tried this:
if(isset(simplexml_load_file($url)));
{
$xml = simplexml_load_file($url);
/*rest of code using $xml*/
}
else {
echo "No info avilable.";
}
But it doesn't work. I guess you can't use ISSET that way. Anyone know how to catch the error?
$xml = file_get_contents("http://myurl.blah");
if (trim($xml) == '') {
die('No content');
}
$xml = simplexml_load_string($xml);
Or, possibly slightly more efficient, but not necessarily recommended because it silences errors:
$xml = #simplexml_load_file($url);
if (!$xml) {
die('error');
}
Don't use isset here.
// Shutdown errors (I know it's bad)
$xml = #simplexml_load_file($url);
// Check you have fetch a response
if (false !== $xml); {
//rest of code using $xml
} else {
echo "No info avilable.";
}
if (($xml = simplexml_load_file($url)) !== false) {
// Everything is OK. Use $xml object.
} else {
// Something has gone wrong!
}
From PHP manual, error handling (click here):
var_dump(libxml_use_internal_errors(true));
// load the document
$doc = new DOMDocument;
if (!$doc->load('file.xml')) {
foreach (libxml_get_errors() as $error) {
// handle errors here
}
libxml_clear_errors();
}
I have a phpBB forum on my localhost for learning purposes..now I'm trying to do this using PHP :
When a link gets posted,a script checks if the exact link exists and if it does then the process of posting the message doesn't continue.
EDIT: This is what I have in includes/message_parser.php
function url_exists($url) {
$handle = #fopen($url, "r");
if ($handle === false){
return false;
fclose($handle);}
else{
return true;
fclose($handle);}}
And this is what I have in posting.php
$your_url = "http://www.somewhere.com/index.php";
$your_url = preg_replace(array('#&\#46;#','#&\#58;#','/\[(.*?)\]/'), array('.',':',''), $your_url);
if (url_exists($your_url))
{
echo 'yeah, its reachable';
}
else
{
echo 'what da hell..';
}
It works. I can see it echoing what da hell when I post a link that exists,but the problem is that the post gets posted. what I want now is,if the link exists,then don't allow the post to be posted.
2ND EDIT:
if($submit){
$URL = "http://www.fileserve.com/file/rP59FZ2";
preg_replace(array('#&\#46;#','#&\#58;#','/\[(.*?)\]/'), array('.',':',''), $url);
if(url_exists($url)) {
echo "Link exists!";
}
That's what I did to prevent submitting the topic when the url exists. not working :\
Checking if link return status code 200 (dunno about 30x)
Using cURL:
function url_exists($url) {
$ch = #curl_init($url);
#curl_setopt($ch, CURLOPT_HEADER, TRUE);
#curl_setopt($ch, CURLOPT_NOBODY, TRUE);
#curl_setopt($ch, CURLOPT_FOLLOWLOCATION, FALSE);
#curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
$status = array();
preg_match('/HTTP\/.* ([0-9]+) .*/', #curl_exec($ch) , $status);
return ($status[1] == 200);
}
// now call the function
$myUrl = "http://www.somewhere.com";
if(url_exists($myUrl)) {
echo "Link exists!";
} else {
echo "Link does not exist :(";
}
Without cURL:
function url_exists($url) {
$h = get_headers($url);
$status = array();
preg_match('/HTTP\/.* ([0-9]+) .*/', $h[0] , $status);
return ($status[1] == 200);
}
// now call the function
$myUrl = "http://www.somewhere.com";
if(url_exists($myUrl)) {
echo "Link exists!";
} else {
echo "Link does not exist :(";
}
You can play around with it :)
UPDATE
To the updated question.
I don't know exactly how phpBB works or where you're trying to catch it, but some suggestions to stop the posting might be to check for the link using javascript/jQuery and then disable the submit button alerting/printing a statement as to why the post wasn't posted.
I'm not that into regex and such, but you would check the post if it contains any link you where looking for, and then "block" the submit of the form.
Something along the lines of:
$('#myform').submit(function(event){
// disable the submit button so the user doesn't spam it
$('#myform input[type=submit]', this).attr('disabled', 'disabled');
// check with regex for the links
// if it's found return true else return false to variable preventSubmit
if(preventSubmit) {
// prevent the form from being submitted
event.preventDefault();
// notify the user
alert("You cannot post that link!");
return false;
}
});
as extra security, you could disable the submit by default, and only enable it once the javascript has loaded.
try:
$url = 'http://www.anyURL.com';
$hndl = #fopen($url,'r');
if($hndl !== false){
echo 'URL Exists';
}
else
{
echo "URL Doesn't exist";
}
First check to see whether the link format is valid:
function isValidURL($url) {
return preg_match('|^http(s)?://[a-z0-9-]+(.[a-z0-9-]+)*(:[0-9]+)?(/.*)?$|i', $url);
}
Then make sure the resource that the link refers to actually exists:
function checkLink() {
$handle = fopen("http://www.example.com/", "r");
if ($handle) { fclose($handle); return true; }
return false;
}