I am trying to create a simple Facebook Page Tab that retrieves current information from my database. I quickly learned that cross-site scripting won't work, as a working demo on the actual website worked great, but produced no results on heroku.
Here is what I have in heroku now. How do I make curl process the page before it returns a result?
<?php
$curl = curl_init();
curl_setopt ($curl, CURLOPT_URL, 'http://www.url.com/output.html');
$result = curl_exec ($curl);
curl_close ($curl);
print $result;
?>
Here is the page that creates the formatted XML that is located on my webserver:
<?php
require_once('connectDB.php');
$xslt_file = "xmlstyle.xsl";
mysql_select_db($database_DB, $db);
$query = sprintf("SELECT * from db");
$result = mysql_query($query, $db) or die(mysql_error());
header("Content-type: text/xml");
$XML = "<?xml version=\"1.0\"?>\n";
if ($xslt_file) $XML .= "<?xml-stylesheet href=\"$xslt_file\" type=\"text/xsl\" ?>";
// root node
$XML .= "<result>\n";
// rows
while ($row = mysql_fetch_array($result, MYSQL_ASSOC)) {
$XML .= "\t<row>\n";
$i = 0;
// cells
foreach ($row as $cell) {
// Escaping illegal characters - not tested actually ;)
$cell = str_replace("&", "&", $cell);
$cell = str_replace("<", "<", $cell);
$cell = str_replace(">", ">", $cell);
$cell = str_replace("\"", """, $cell);
$col_name = mysql_field_name($result,$i);
// creates the "<tag>contents</tag>" representing the column
$XML .= "\t\t<" . $col_name . ">" . $cell . "</" . $col_name . ">\n";
$i++;
}
$XML .= "\t</row>\n";
}
$XML .= "</result>\n";
// output the whole XML string
echo $XML;
?>
I'm sure I'm over complicating this whole thing, but it has been somewhat enjoyable to try to make it work. If there is a much easier way to get the same result, I'm all ears. Thanks in advance.
Use the RETURNTRANSFER option:
//Set curl to return the page instead of sending it to the browser
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
References
curl manpage
PHP curl binding
Related
I have the following php code. I am able to get the value stored in my variable and printed. But after json_encode, the value became 'empty'. Is there a bug in json_encode ? I am using Php 7.2 on ubuntu 18
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,'https://www.thestar.com.my/rss/news/nation');
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$xml = curl_exec($ch);
curl_close($ch);
$rss = simplexml_load_string($xml);
$cnt = count($rss->channel->item);
$items = array();
$items[0]['title'] = $rss->channel->item[0]->title;
$items[0]['url'] = $rss->channel->item[0]->link;
echo $items[0]['title'] . PHP_EOL;
echo $items[0]['url'] . PHP_EOL;
echo json_encode($items) . PHP_EOL;
?>
See the output below. What is wrong with the json_encode ? Why after the json_encode, the title became empty ?
Sabah updates SOPs for places of worship and childcare centres
https://www.thestar.com.my/news/nation/2021/06/13/sabah-updates-sops-for-places-of-worship-and-childcare-centres
[{"title":{"0":{}},"url":{"0":"https:\/\/www.thestar.com.my\/news\/nation\/2021\/06\/13\/sabah-updates-sops-for-places-of-worship-and-childcare-centres"}}]
json_encode produces an empty object tag ({}) when passed PHP objects that do not implement JsonSerializable or contain public member variables.
You pass it \SimpleXMLElement nodes, not strings.
In your echo it just shows because the XML entities implement __toString() which echo invokes.
Either do that aswell or cast it to (string):
<?php
$rss = simplexml_load_string($xml);
$items = array();
$items[0]['title'] = $rss->channel->item[0]->title->__toString();
$items[0]['url'] = (string) $rss->channel->item[0]->link;
echo json_encode($items) . PHP_EOL;
?>
Thanks..Got it with
$items[0]['title'] = $rss->channel->item[0]->title->__toString();
I am trying to call an external site (API) which will return an XML response. I have tried several ways of doing this and end up with the same response: Premature end of file. Unfortunately I am not able to get any positive feedback from the other site. Below are the php commands I have tried and their results. It woud appear to me that there is an issue on the other site. I can copy the URL and paste into a browser and it works just fine.
$url = "https://cli-cert.emdeon.com/servlet/XMLServlet?request=<?xml version='1.0'?>";
$url .= "<REQUEST userid='p_panda1' password='practice00' facility='3003154010'>";
$url .= "<OBJECT name='clinicalreport' op='search_filedelivery'>";
$url .= "<receivingorganization>3003154010</receivingorganization>";
$url .= "<creation_datetime_from>09/01/2014</creation_datetime_from>";
$url .= "<creation_datetime_to>10/10/2014</creation_datetime_to>";
$url .= "<is_downloaded>n</is_downloaded></OBJECT></REQUEST>";
$myXML = simplexml_load_file($url);
echo "<pre>";
print_r($myXML);
$postdata = file_get_contents($url);
echo "<pre>";
print_r($postdata);
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
echo "<pre>";
echo $response,"<br>";
Output from the echo commands:
SimpleXMLElement Object
(
[0] => Premature end of file.
)
Premature end of file.
Premature end of file.
The URL you are creating is invalid.
You are creating a URL like:
https://cli-cert.emdeon.com/servlet/XMLServlet?request=<?xml version='1.0'?>...
Which would mean you have 2 questionmarks in it. Also for example < is not a valid url character as far as I know.
So you would have to url-encode that, like:
$request = '<?xml version='1.0'?>...etc...';
$url = "https://cli-cert.emdeon.com/servlet/XMLServlet?request=". urlencode($request);
You need to urlencode the parameter. Look at http://php.net/manual/en/function.urlencode.php for more info. After changing it to this, all 3 come back with a response.
$url = "https://cli-cert.emdeon.com/servlet/XMLServlet?request=";
$xml = "<?xml version='1.0'?>";
$xml .= "<REQUEST userid='p_panda1' password='practice00' facility='3003154010'>";
$xml .= "<OBJECT name='clinicalreport' op='search_filedelivery'>";
$xml .= "<receivingorganization>3003154010</receivingorganization>";
$xml .= "<creation_datetime_from>09/01/2014</creation_datetime_from>";
$xml .= "<creation_datetime_to>10/10/2014</creation_datetime_to>";
$xml .= "<is_downloaded>n</is_downloaded></OBJECT></REQUEST>";
$url = $url . urlencode($xml);
I have two computers, comp 1 as branch 1 and comp 2 as main branch. in comp 1 i have generated an xml of my database query using php.
`<?php
header ("Content-Type:text/xml");
//database configuration
$config['mysql_host'] = "localhost";
$config['mysql_user'] = "root";
$config['mysql_pass'] = "donnaluz";
$config['db_name'] = "global89_branch1";
$config['table_name'] = "branchsales";
//connect to host
mysql_connect($config['mysql_host'],$config['mysql_user'],$config['mysql_pass']);
//select database
#mysql_select_db($config['db_name']) or die( "Unable to select database");
$xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
$root_element = $config['table_name'];
$xml = "<$root_element>";
/*$title = $doc->createElement("branchsales");
$title = $root->appendChild($title);
$text = $doc->createTextNode("sales");
$text = $title->appendChild($text);
*/
//select all items in table
$sql = "SELECT branch.branchname,branchadmin.username,branchcomp.*,branchsales.*,days.day
FROM branchsales,branch,branchadmin,branchcomp,days
WHERE
branchsales.comp_id = branchcomp.comp_id
AND branchsales.admin_id = branchadmin.admin_id
AND branchsales.branch_id = branch.branch_id
AND branchsales.day_id = days.day_id";
$result = mysql_query($sql);
if (!$result) {
die('Invalid query: ' . mysql_error());
}
if(mysql_num_rows($result)>0)
{
while($result_array = mysql_fetch_assoc($result))
{
$xml .= "<".$config['table_name'].">";
//loop through each key,value pair in row
foreach($result_array as $key => $value)
{
//$key holds the table column name
$xml .= "<$key>";
//embed the SQL data in a CDATA element to avoid XML entity issues
$xml .= "<![CDATA[$value]]>";
//and close the element
$xml .= "</$key>";
}
$xml.="</".$config['table_name'].">";
}
//close the root element
$xml .= "</$root_element>";
//send the xml header to the browser
header ("Content-Type:text/xml");
echo $xml;
?>
` which looks like this
<branchsales>
<branchname>Branch1</branchname>
<username>garfield</username>
<comp_id>1</comp_id>
<admin_id>1</admin_id>
<pcnum>1</pcnum>
<starttime>09:00:00</starttime>
<endtime>10:00:00</endtime>
<totaltime>1:00:00</totaltime>
<compcharge>10.00</compcharge>
<id>1</id>
<branch_id>1</branch_id>
<day_id>5</day_id>
<timeopened>8:00:00</timeopened>
<timeclosed>23:00:00<timeclosed>
blah blah.. so on..
The thing is, I want that generated xml to be sent out to comp 2,
looking like this in a table
|ID|Day |Watcher |Branch | Current Date | Time Opened | Time closed | PC No. | so on...
1 Friday garfield Branch1 29-03-13 8:00:00 23:00:00 1
THIS IS MY SEND CODE, BUT ITS NOT WORKING
<?
php
$file = 'http://localhost/thesis/xmldailyrep.php';
$xml_builder = 'simplexml_load_file($file)';
$ch = curl_init("http://172.16.0.55/dailyrep1.php");
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type:text/xml'));
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml_builder);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0);
curl_setopt($ch, CURLOPT_REFERER, "http://localhost/thesis/xmldailyrep.php");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$ch_result = curl_exec($ch);
curl_close($ch);
echo $ch_result;
?>
MY RECEIVE CODE IN COMP 2 is this
<?php
/*
* XML Server.
*/
// We use php://input to get the raw $_POST results.
$xml_post = file_get_contents('xmldailyrep.php');
// If we receive data, save it.
if ($xml_post) {
$xml_file = 'received_xml_' . date('Y_m_d-H-i-s') . '.xml';
$fh = fopen($xml_file, 'w') or die();
fwrite($fh, $xml_post);
fclose($fh);
// Return, as we don't want to cause a loop by processing the code below.
return;
}
?>
PLEASE HELP
As far as I know, from the title. I will use frameworks to do this work. Like Apache Camel, Mule ESB. If its going to be a large scale implementation.
If you can tell us the whole story, it could be easier to help you.
-Guru
#gnanagurus
$file = 'http://localhost/thesis/xmldailyrep.php';
$xml_builder = file_get_contents($file);
I have just a PHP script for HTML parsing and it works on simple web sites, but now I need to parse the cinema program from this website. I am using the file_get_contents function, which returns just 4 new line delimiters \n and I just can't figure out why.
The website itself will be more difficult to parse with DOMDocument a XPath because the program itself is just pop-up window and it doesn't seem to change the URL address but I will try to handle this problem after retrieving the HTML code of the site.
Here is the shortened version of my script:
<?php
$url = "http://www.cinemacity.cz/";
$content = file_get_contents($url);
$dom = new DomDocument;
$dom->loadHTML($content);
if ($dom == FALSE) {
echo "FAAAAIL\n";
}
$xpath = new DOMXPath($dom);
$tags = $xpath->query("/html");
foreach ($tags as $tag) {
var_dump(trim($tag->nodeValue));
}
?>
EDIT:
So, following the advice by WBAR (thank you), I was looking for a way how to change the header in file_get_contents() function a this is the answer I've found elsewhere. Now I am able to obtain the HTML of the site, hopefully I will manage parsing of this mess :D
<?php
libxml_use_internal_errors(true);
// Create a stream
$opts = array(
'http'=>array(
'user_agent' => 'PHP libxml agent', //Wget 1.13.4
'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
$content = file_get_contents('http://www.cinemacity.cz/', false, $context);
$dom = new DomDocument;
$dom->loadHTML($content);
if ($dom == FALSE) {
echo "FAAAAIL\n";
}
$xpath = new DOMXPath($dom);
$tags = $xpath->query("/html");
foreach ($tags as $tag) {
var_dump(trim($tag->nodeValue));
}
?>
The problem is not in PHP but in target host. It detects client's User-Agent header. Look at this:
wget http://www.cinemacity.cz/
2012-10-07 13:54:39 (1,44 MB/s) - saved `index.html.1' [234908]
but when remove User-Agent headers:
wget --user-agent="" http://www.cinemacity.cz/
2012-10-07 13:55:41 (262 KB/s) - saved `index.html.2' [4/4]
Only 4 bytes were returned by the server
Try to get the contents this way:
function get2url($url, $timeout = 30, $port = 80, $buffer = 128) {
$arr = parse_url($url);
if(count($arr) < 3) return "URL ERROR";
$ssl = "";
if($arr['scheme'] == "https") $ssl = "ssl://";
$header = "GET " . $arr['path'] . "?" . $arr['query'] . " HTTP/1.0\r\n";
$header .= "Host: " . $arr['host'] . "\r\n";
$header .= "\r\n";
$f = #fsockopen($ssl . $arr['host'], $port, $errno, $errstr, $timeout);
if(!$f)
return $errstr . " (" . $errno . ")";
else{
#fputs($f, $header . $arr['query']);
$echo = "";
while(!feof($f)) { $echo .= #fgets($f, $buffer); }
#fclose($f);
return $echo;
}
}
You will have to remove the headers though.
I'm trying to make a script, which search the list of urls given in the form for the email adresses. Could anyone advice me how to do it? Is there some alternative to cURL?
I tried to make it with file_get_contents, but the script analyze only the last url given in the form: when I enter for example two urls to the form, the first "print_r("show current_url:". $current_url); is empty and for the second it shows the page(url) content(without pictures).
I asked on different forums, but received no answer. Will really appraciate your help.
Thank you
$urls = explode("\n", $_POST['urls']);
$db = new mysqli('localhost', 'root', 'root', 'urls');
if (mysqli_connect_errno()) {
echo 'Błąd: ';
exit;
}
for ($i=0; $i<count($urls); $i++){
print_r("show link:". $urls[$i]."<br>");
$current_url = file_get_contents($urls[$i]);
print_r("show current_url:". $current_url);
preg_match( "/[\._a-zA-Z0-9-]+#[\._a-zA-Z0-9-]+/i", $current_url, $email);//email
print_r ("show email:".$email[0]);
$query = "INSERT INTO urle set adres = '$email[0]' ";
$result = $db->query($query);
}
if ($query) {
echo $db->affected_rows ."pozycji dodano.";
} else {
echo mysql_errno() . ":" . mysql_error() . "Wystąpił błąd przy dodawaniu urli ";
}
$db->close();
?>
EDIT:
I have tried with curl. var_dump($email); shows: array(0) { }
The script displays now all of the urls given in the form in the browser, but preg_match doesn't work, so it doesn't extract email adresses.
<?php
$urls = explode("\n", $_POST['urls']);
$db = new mysqli('localhost', 'root', 'root', 'linki');
if (mysqli_connect_errno()) {
echo 'Błąd: ';
exit;
}
for ($i=0; $i<count($urls); $i++){
$url = $urls[$i];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_URL, $url);
$output = curl_exec($ch);
preg_match( "/[\._a-zA-Z0-9-]+#[\._a-zA-Z0-9-]+/i", $output, $email);//email
var_dump($email);
$query = "INSERT INTO urle set adres = '$email[0]' ";
$result = $db->query($query);
curl_close($ch);
}//
if ($result) {
echo $db->affected_rows ."pozycji dodano.";
} else {
echo mysql_errno() . ":" . mysql_error() . "Wystąpił błąd przy dodawaniu urli ";
}
$db->close();
?>
Is there some alternative to cURL?
file_get_contents, which doesn't give you any error messages (unless error_reporting is raised), and which is often blocked unless ini_set("user_agent", ...) was set.
Alternatively HttpRequest on newer PHP installations.
Still curl is not difficult to use. The manual is full of examples.
the first "print_r("show current_url:". $current_url); is empty
Nobody can tell. It's your duty to debug that (especially since you haven't mentioned the affected url in your question). Use curl or httprequest.
Ok, i've fixed it!!!:)
Here is the code:
for ($i=0; $i<count($linki); $i++){
$url = $linki[$i];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result =curl_exec($ch);
curl_close($ch);
preg_match("/[-a-z0-9\._]+#[-a-z0-9\._]+\.[a-z]{2,4}/", $result, $email);//email
print_r($email);
$zapytanie = "INSERT INTO urle set adres = '$email[0]' ";
$wynik = $db->query($zapytanie);
}