PHP's strlen function behaving strangely - php

Please consider the following code:
$imagePath = "https://s22.postimg.org/3k3o9ly8t/testigo.jpg";
$imagedata = get that image data through curl and store in this variable;
echo strlen($imagedata); // outputs 4699
if(strlen($imagedata) == 4699 ) {
echo "length is 4699";
}
The above if-condition never becomes true even though the strlen value is 4600. It seems very strange; am I missing anything? I've already tried mb_strlen, but to no avail.
Update:
It seems to work for certain images, but not for the following image.
Code:
$strImageURL = "https://s22.postimg.org/3k3o9ly8t/testigo.jpg";
$strImageData = getData($strImageURL);
echo "<br />" . strlen($strImageData);
if(strlen($strImageData) === 4699) {
echo "true";
}
function getData($strSubmitURL)
{
$strData = null;
$ch = curl_init();
//return parameter
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 120);
curl_setopt($ch, CURLOPT_TIMEOUT, 140);
//site name
curl_setopt($ch, CURLOPT_URL,$strSubmitURL);
// don' verify ssl host
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER,false);
$strData = curl_exec ($ch);
if (!$strData) {
//die ("cURL error: " . curl_error ($ch) . "\n");
return '';
}
curl_close ($ch);
unset($ch);
return $strData;
}

This works for me:
$url = "http://static.bbci.co.uk/frameworks/barlesque/2.51.4/orb/4/img/bbc-blocks-dark.png";
$imagedata = file_get_contents($url);
//echo strlen($imagedata); // outputs 1020
if(strlen($imagedata) == 1020 ) {
echo "length is 1020";
}
And as further troubleshooting, I would try a var_dump(get_defined_vars()); at the end of your code and inside the if statement to see whats going on.
//Edit/Update:
Using your url, and also putting in a var dump twice:
$url = "http://s22.postimg.org/3k3o9ly8t/testigo.jpg";
$imagedata = file_get_contents($url);
$strlen = strlen($imagedata); // outputs 4669
var_dump($strlen);
if($strlen == 4669 ) {
echo "length is 4669 \n";
var_dump($strlen);
}
returns:
PhpMate running PHP 5.3.15 with (/usr/bin/php)
>>> untitled
int(4669)
length is 4669
int(4669)

strlen() is used to count the bytes that a string equates an one character does not necessarily equal 1 byte in UTF-8
Another issue could be type-casting since PHP has such loose rules about this. Would this work for you?
if((int)strlen($imagedata) == 4600 ) {
echo "length is 4600";
}
or
if(strlen($imagedata) == '4600' ) {
echo "length is 4600";
}

Related

Sending XML post request using API

I am attempting to make an xml post request which hit the other server url and post xml data their but the code not working for me here is my code
if ($mail->send()) {
$URL = "server link api based";
$ch = curl_init($URL);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/xml','Content-Length: ' . strlen($xml)));
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$output = curl_exec($ch);
curl_close($ch);
// echo $output;
if ($output) {
echo "1";
} else {
echo "2";
}
}
} catch (Exception $e) {
echo $e;
}
XML format of data here is the code of xml format
$xml = '<?xml version="1.0" encoding="UTF-8"?>
<data>
<lead>
<key>YaskjdfweuYksdlksid....</key>
<leadgroup>.....</leadgroup>
<site>.....</site>
<introducer>0</introducer>
<source>FDH Quick submission</source>
<medium>FDH Quick submission</medium>
<firstname>' . $firstName . '</firstname>
<lastname>' . $lastName . '</lastname>
<email>' . $userEmail . '</email>
<postcode>' . $postCode . '</postcode>
<contactphone>Yes</contactphone>
<phone1>' . $userPhoneNo . '</phone1>
</lead>
</data>';
1 possible issue is that you're not escaping your strings as you insert them in your XML, which might leave you with a corrupt XML file (eg, & must be escaped as &, < must become <, ' must become &apos;, and so on)
you can xml-encode strings with this function:
function xml_esacpe(string $str, string $charset = 'UTF-8'): string {
if (! strlen ( $str )) {
return "";
}
$ret = htmlspecialchars ( $str, ENT_QUOTES | ENT_SUBSTITUTE | ENT_DISALLOWED | ENT_XML1, $charset, true );
if (! strlen ( $ret )) {
throw new Exception ( "failed to xml-encode input! (most likely wrong charset or corrupted input)" );
}
return $ret;
}
furthermore, you can verify that your XML is valid by doing $isValidXML=#((new DOMDocument())->loadXML($xml)); - it will now be true if the xml is valid, or false if the xml is invalid. - is the xml you're sending actually valid xml?
but in any case, you must elaborate what you mean by the code not working for me - how is it not working?

How to check if link is downloadable file in php? [duplicate]

This question already has answers here:
What is the best way to check if a URL exists in PHP?
(5 answers)
Closed 7 years ago.
I'm trying to make broken link checker with php.
I modified some php code i found online i'm not php programmer.
It let's in some unbroken link's but thats ok.
However I have problem with all presentation, zips and so on...
Basicly if it is downlaod then algorithm thinks it's a dead link.
<?php
set_time_limit(0);
//ini_set('memory_limit','512M');
$servername = "localhost";
$username = "";
$password = "";
try {
$conn = new PDO("mysql:host=$servername;dbname=test", $username, $password);
// set the PDO error mode to exception
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
echo "Connected successfully" . "<br />";
echo "----------------------------------------------------<br />";
}
catch (PDOException $e) {
echo "Connection failed: " . $e->getMessage();
}
$sql = "SELECT object,value FROM metadata where xpath = 'lom/technical/location'";
$result = $conn->query($sql)->fetchAll(PDO::FETCH_ASSOC);
//print_r($result);
$array_length = sizeof($result); //26373
//$array_length = 26373;
$i = 0;
$myfile = fopen("Lom_Link_patikra1.csv", "w") or die("Unable to open file!");
$menu_juosta = "Objektas;Nuoroda;Klaidos kodas;\n";
//fwrite($myfile,$menu_juosta);
for ($i; $i < $array_length; $i++) {
$new_id = $result[$i]["object"];
$sql1 = "SELECT published from objects where id ='$new_id'";
$result_published = $conn->query($sql1)->fetchAll(PDO::FETCH_ASSOC);
//print_r ($result_published);
if ($result_published[0]["published"] != 0) {
$var1 = $result[$i]["value"];
$var1 = str_replace('|experience|902', '', $var1);
$var1 = str_replace('|packed_in|897', '', $var1);
$var1 = str_replace('|packed_in|911', '', $var1);
$var1 = str_replace('|packed_in|895', '', $var1);
$request_response = check_url($var1); // Puslapio atsakymas
if ($request_response != 200) {
$my_object = $result[$i]["object"] . ";" . $var1 . ";" . $request_response . ";\n";
fwrite($myfile, $my_object);
}
}
}
fclose($myfile);
$conn = null;
function check_url($url)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$data = curl_exec($ch);
$headers = curl_getinfo($ch);
curl_close($ch);
return $headers['http_code'];
}
Link example : http://lom.emokykla.lt/MO/Matematika/pazintis_su_erdviniais%20_kunais_1.doc
Any solutions, advice?
Thank you all for help.Now it works way faster. It seems there is problem with blank spaces, but that's even intriguing.
As it seems the problem i had was in understanding, how http status is working, like what it return's and why. Link's that i had marked as bad,but working where 301 or 302 - Redirect's.
https://en.wikipedia.org/wiki/List_of_HTTP_status_codes
Thank you all for help.
Using CURL for remote file
function checkRemoteFile($url)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$url);
// don't download content
curl_setopt($ch, CURLOPT_NOBODY, 1);
curl_setopt($ch, CURLOPT_FAILONERROR, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
if(curl_exec($ch)!==FALSE)
{
return true;
}
else
{
return false;
}
}
EDIT: I may have misunderstood you but if you just want to check if the url actually exists than the code below will be all you need.
function url_exists($url) {
if(#file_get_contents($url,0,NULL,0,1))
{return 1;}
else
{return 0;}
}
curlopt_nobody set to TRUE makes a HTTP HEAD request instead of a GET request, so try using curl_setopt( $ch, CURLOPT_NOBODY, true );
Try to use file_exists method : http://php.net/manual/fr/function.file-exists.php

php code for powerpoint2pdf in convertapi not working

I use the following to convert a doc file to pdf in PHP:
function CallToApi($fileToConvert, $pathToSaveOutputFile, $apiKey, &$message,$unique_filename)
{
try
{
$fileName = $unique_filename.".pdf";
$postdata = array('OutputFileName' => $fileName, 'ApiKey' => $apiKey, 'file'=>"#".$fileToConvert);
$ch = curl_init("http://do.convertapi.com/word2pdf");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postdata);
$result = curl_exec($ch);
$headers = curl_getinfo($ch);
$header=ParseHeader(substr($result,0,$headers["header_size"]));
$body=substr($result, $headers["header_size"]);
curl_close($ch);
if ( 0 < $headers['http_code'] && $headers['http_code'] < 400 )
{
// Check for Result = true
if (in_array('Result',array_keys($header)) ? !$header['Result']=="True" : true)
{
$message = "Something went wrong with request, did not reach ConvertApi service.<br />";
return false;
}
// Check content type
if ($headers['content_type']<>"application/pdf")
{
$message = "Exception Message : returned content is not PDF file.<br />";
return false;
}
$fp = fopen($pathToSaveOutputFile.$fileName, "wbx");
fwrite($fp, $body);
$message = "The conversion was successful! The word file $fileToConvert converted to PDF and saved at $pathToSaveOutputFile$fileName";
return true;
}
else
{
$message = "Exception Message : ".$result .".<br />Status Code :".$headers['http_code'].".<br />";
return false;
}
}
catch (Exception $e)
{
$message = "Exception Message :".$e.Message."</br>";
return false;
}
}
I now want to use the same to convert a ppt to pdf. For which I change
$ch = curl_init("http://do.convertapi.com/word2pdf");
to
$ch = curl_init("http://do.convertapi.com/PowerPoint2Pdf");
but I am not sure why it isnt converting the given input. Is there something that I may be missing?
It's due to PHP 5.6.
You need to add this line to your code as well
curl_setopt($ch, CURLOPT_SAFE_UPLOAD, false);
See:Backward incompatible changes (at the bottom).

check a url is valid or not and valid XML in php

I'm wanted to read a rss feed and store it.for this I m using:-
<?php
$homepage = file_get_contents('http://www.forbes.com/news/index.xml');
$xml = simplexml_load_string($homepage);
echo '<pre>';
print_r($xml);
?>
but first I want to check
1.URL is valid or not ,means if its response time of
$homepage = file_get_contents('http://www.forbes.com/news/index.xml');
is less than 1 minutes and the url address is correct
2.Then check the File(http://www.forbes.com/news/index.xml) have a valid XML data or not.
if valid XML then show response time else show error.
answer Of MY QUESTION:
Thanks everybody for your help and suggestion.I solved this problem. for this I wrote this code
<?php
// function() for valid XML or not
function XmlIsWellFormed($xmlContent, $message) {
libxml_use_internal_errors(true);
$doc = new DOMDocument('1.0', 'utf-8');
$doc->loadXML($xmlContent);
$errors = libxml_get_errors();
if (empty($errors))
{
return true;
}
$error = $errors[ 0 ];
if ($error->level < 3)
{
return true;
}
$lines = explode("r", $xmlContent);
$line = $lines[($error->line)-1];
$message = $error->message . ' at line ' . $error->line . ': ' . htmlentities($line);
return false;
}
//function() for checking URL is valid or not
function Visit($url){
$agent = $ch=curl_init();
curl_setopt ($ch, CURLOPT_URL,$url );
curl_setopt($ch, CURLOPT_USERAGENT, $agent);
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt ($ch,CURLOPT_VERBOSE,false);
curl_setopt($ch, CURLOPT_TIMEOUT, 60);
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch,CURLOPT_SSLVERSION,3);
curl_setopt($ch,CURLOPT_SSL_VERIFYHOST, FALSE);
$page=curl_exec($ch);
//echo curl_error($ch);
$httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if($httpcode>=200 && $httpcode<300) return true;
else return false;
}
$url='http://www.forbes.com/news/index.xml';
if (Visit($url)){
$xmlContent = file_get_contents($url);
$errorMessage = '';
if (XmlIsWellFormed($xmlContent, $errorMessage)) {
echo 'xml is valid';
$xml = simplexml_load_string($xmlContent);
echo '<pre>';
print_r($xml);
}
}
?>
If the url is not valid file_get_contents would fail.
To check if the xml is valid
simplexml_load_string(file_get_contents('http://www.forbes.com/news/index.xml'))
That would return true if its and would fail entirely if it isn't.
if(simplexml_load_string(file_get_contents('http://www.forbes.com/news/index.xml'))){
echo "yeah";
}else { echo "nah";}
This page has a snippet with a validator for a URL using regular expressions. The function and usage:
function isValidURL($url)
{
return preg_match('|^http(s)?://[a-z0-9-]+(.[a-z0-9-]+)*(:[0-9]+)?(/.*)?$|i', $url);
}
if(!isValidURL($fldbanner_url))
{
$errMsg .= "* Please enter valid URL including http://<br>";
}
if (!filter_var('anyurl',FILTER_VALIDATE_URL))
echo "Wrong url";
end;
http://php.net/manual/en/filter.filters.validate.php

PHP: Check if URL redirects?

I have implemented a function that runs on each page that I want to restrict from non-logged in users. The function automatically redirects the visitor to the login page in the case of he or she is not logged in.
I would like to make a PHP function that is run from a exernal server and iterates through a number of set URLs (array with URLs that is for each protected site) to see if they are redirected or not. Thereby I could easily make sure if protection is up and running on every page.
How could this be done?
Thanks.
$urls = array(
'http://www.apple.com/imac',
'http://www.google.com/'
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
foreach($urls as $url) {
curl_setopt($ch, CURLOPT_URL, $url);
$out = curl_exec($ch);
// line endings is the wonkiest piece of this whole thing
$out = str_replace("\r", "", $out);
// only look at the headers
$headers_end = strpos($out, "\n\n");
if( $headers_end !== false ) {
$out = substr($out, 0, $headers_end);
}
$headers = explode("\n", $out);
foreach($headers as $header) {
if( substr($header, 0, 10) == "Location: " ) {
$target = substr($header, 10);
echo "[$url] redirects to [$target]<br>";
continue 2;
}
}
echo "[$url] does not redirect<br>";
}
I use curl and only take headers, after I compare my url and url from header curl:
$url="http://google.com";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_TIMEOUT, '60'); // in seconds
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_NOBODY, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$res = curl_exec($ch);
if(curl_getinfo($ch)['url'] == $url){
echo "not redirect";
}else {
echo "redirect";
}
You could always try adding:
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
since 302 means it moved, allow the curl call to follow it and return whatever the moved url returns.
Getting the headers with get_headers() and checking if Location is set is much simpler.
$urls = [
"https://example-1.com",
"https://example-2.com"
];
foreach ($urls as $key => $url) {
$is_redirect = does_url_redirect($url) ? 'yes' : 'no';
echo $url . ' is redirected: ' . $is_redirect . PHP_EOL;
}
function does_url_redirect($url){
$headers = get_headers($url, 1);
if (!empty($headers['Location'])) {
return true;
} else {
return false;
}
}
I'm not sure whether this really makes sense as a security check.
If you are worried about files getting called directly without your "is the user logged in?" checks being run, you could do what many big PHP projects do: In the central include file (where the security check is being done) define a constant BOOTSTRAP_LOADED or whatever, and in every file, check for whether that constant is set.
Testing is great and security testing is even better, but I'm not sure what kind of flaw you are looking to uncover with this? To me, this idea feels like a waste of time that will not bring any real additional security.
Just make sure your script die() s after the header("Location:...") redirect. That is essential to stop additional content from being displayed after the header command (a missing die() wouldn't be caught by your idea by the way, as the redirect header would still be issued...)
If you really want to do this, you could also use a tool like wget and feed it a list of URLs. Have it fetch the results into a directory, and check (e.g. by looking at the file sizes that should be identical) whether every page contains the login dialog. Just to add another option...
Do you want to check the HTTP code to see if it's a redirect?
$params = array('http' => array(
'method' => 'HEAD',
'ignore_errors' => true
));
$context = stream_context_create($params);
foreach(array('http://google.com', 'http://stackoverflow.com') as $url) {
$fp = fopen($url, 'rb', false, $context);
$result = stream_get_contents($fp);
if ($result === false) {
throw new Exception("Could not read data from {$url}");
} else if (! strstr($http_response_header[0], '301')) {
// Do something here
}
}
I hope it will help you:
function checkRedirect($url)
{
$headers = get_headers($url);
if ($headers) {
if (isset($headers[0])) {
if ($headers[0] == 'HTTP/1.1 302 Found') {
//this is the URL where it's redirecting
return str_replace("Location: ", "", $headers[9]);
}
}
}
return false;
}
$isRedirect = checkRedirect($url);
if(!$isRedirect )
{
echo "URL Not Redirected";
}else{
echo "URL Redirected to: ".$isRedirect;
}
You can use session,if the session array is not set ,the url redirected to a login page.
.
I modified Adam Backstrom answer and implemented chiborg suggestion. (Download only HEAD). It have one thing more: It will check if redirection is in a page of the same server or is out. Example: terra.com.br redirects to terra.com.br/portal. PHP will considerate it like redirect, and it is correct. But i only wanted to list that url that redirect to another URL. My English is not good, so, if someone found something really difficult to understand and can edit this, you're welcome.
function RedirectURL() {
$urls = array('http://www.terra.com.br/','http://www.areiaebrita.com.br/');
foreach ($urls as $url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// chiborg suggestion
curl_setopt($ch, CURLOPT_NOBODY, true);
// ================================
// READ URL
// ================================
curl_setopt($ch, CURLOPT_URL, $url);
$out = curl_exec($ch);
// line endings is the wonkiest piece of this whole thing
$out = str_replace("\r", "", $out);
echo $out;
$headers = explode("\n", $out);
foreach($headers as $header) {
if(substr(strtolower($header), 0, 9) == "location:") {
// read URL to check if redirect to somepage on the server or another one.
// terra.com.br redirect to terra.com.br/portal. it is valid.
// but areiaebrita.com.br redirect to bwnet.com.br, and this is invalid.
// what we want is to check if the address continues being terra.com.br or changes. if changes, prints on page.
// if contains http, we will check if changes url or not.
// some servers, to redirect to a folder available on it, redirect only citting the folder. Example: net11.com.br redirect only to /heiden
// only execute if have http on location
if ( strpos(strtolower($header), "http") !== false) {
$address = explode("/", $header);
print_r($address);
// $address['0'] = http
// $address['1'] =
// $address['2'] = www.terra.com.br
// $address['3'] = portal
echo "url (address from array) = " . $url . "<br>";
echo "address[2] = " . $address['2'] . "<br><br>";
// url: terra.com.br
// address['2'] = www.terra.com.br
// check if string terra.com.br is still available in www.terra.com.br. It indicates that server did not redirect to some page away from here.
if(strpos(strtolower($address['2']), strtolower($url)) !== false) {
echo "URL NOT REDIRECT";
} else {
// not the same. (areiaebrita)
echo "SORRY, URL REDIRECT WAS FOUND: " . $url;
}
}
}
}
}
}
function unshorten_url($url){
$ch = curl_init();
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_URL, $url);
$out = curl_exec($ch);
$real_url = $url;//default.. (if no redirect)
if (preg_match("/location: (.*)/i", $out, $redirect))
$real_url = $redirect[1];
if (strstr($real_url, "bit.ly"))//the redirect is another shortened url
$real_url = unshorten_url($real_url);
return $real_url;
}
I have just made a function that checks if a URL exists or not
$ch = curl_init();
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
function url_exists($url, $ch) {
curl_setopt($ch, CURLOPT_URL, $url);
$out = curl_exec($ch);
// line endings is the wonkiest piece of this whole thing
$out = str_replace("\r", "", $out);
// only look at the headers
$headers_end = strpos($out, "\n\n");
if( $headers_end !== false ) {
$out = substr($out, 0, $headers_end);
}
//echo $out."====<br>";
$headers = explode("\n", $out);
//echo "<pre>";
//print_r($headers);
foreach($headers as $header) {
//echo $header."---<br>";
if( strpos($header, 'HTTP/1.1 200 OK') !== false ) {
return true;
break;
}
}
}
Now I have used an array of URLs to check if a URL exists as following:
$my_url_array = array('http://howtocode.pk/result', 'http://google.com/jobssss', 'https://howtocode.pk/javascript-tutorial/', 'https://www.google.com/');
for($j = 0; $j < count($my_url_array); $j++){
if(url_exists($my_url_array[$j], $ch)){
echo 'This URL "'.$my_url_array[$j].'" exists. <br>';
}
}
I can't understand your question.
You have an array with URLs and you want to know if user is from one of the listed URLs?
If I'm right in understanding your quest:
$urls = array('http://url1.com','http://url2.ru','http://url3.org');
if(in_array($_SERVER['HTTP_REFERER'],$urls))
{
echo 'FROM ARRAY';
} else {
echo 'NOT FROM ARR';
}

Categories