Why using DOMDocument makes site load slower? - php

I'm using DOMDocument with xpath to load some data to my site from external (fast) website.
Right now I use 4 urls (please see below). I need to increase to 8 urls.
What I have noticed, that the more of those you add, the more slower the site loads.
Is there any way to use xpath for more faster load?
Or maybe there's at least some kind of a way to load the data on website1 (child website) and when it loads, include the data to my main website.
Any tips would be appeciated.
<?php
$parent_title = get_the_title( $post->post_parent );
$html_string = file_get_contents('weburladresshere');
$dom = new DOMDocument();
libxml_use_internal_errors(true);
$dom->loadHTML($html_string);
libxml_clear_errors();
$xpath = new DOMXpath($dom);
$values = array();
$row = $xpath->query('myquery');
foreach($row as $value) {
print($value->nodeValue);
}
?>

It's slow because you load external sites. Instead of loading them just in time try to load them "in the background" via another php job and save them to a temporary file. Then you can load the html from your local temp file which is faster than the loading the remote $html_string via file_get_contents.
Extended answer
Here you can see a very leightweight example of how you could handle it.
function getPageContent($url) {
$filename = md5($url).'.tmp';
// implement your extended cache logic here
// for example: store it just for 60 seconds...
if(!file_exists($filename)) {
file_put_contents($filename, $url);
}
return file_get_contents($filename);
}
function businessLogic($url) {
$htmlContent = getPageContent($url);
// your business logic here
}
businessLogic($url);

Related

Laravel 5 Include blade templates dynamically (replace div)

I have a CMS where users can create and edit their own content in their websites. I also provide the possibility to include forms and galleries by simply replacing specific Div's in their content.
In the past I simply exploded the content on these Div's to an array, replaced the whole Div's with the needed html code (by using PHP's include) to show the form or gallery at that exact position, imploded the whole array to a string again (html) and used in the website.
Now I am trying to achieve the same in Laravel 5:
// example plugins div in HTML
// ******************************
<div class="plugin form"></div>
// PageController.php
// ******************************
$page = Page::where(('url', '=', "home")->first();
$page->text = Helpers::getPlugins($page->text);
// Helpers.php (a non default custom class with functions)
// ******************************
public static function getPlugins($page)
{
$dom = new DOMDocument();
$dom->loadHTML($page, LIBXML_HTML_NOIMPLIED);
$x = $dom->getElementsByTagName("div");
foreach ($x as $node)
{
if (strstr($node->getAttribute('class'), "plugin"))
{
$plugin = explode(" ",$node->getAttribute('class'));
$filename = base_path() . "/resources/views/plugins/" . trim($plugin[1]) . ".blade.php";
if (is_file($filename))
{
ob_start();
include($filename);
ob_get_contents();
$node->nodeValue = ob_get_clean();
}
else
{
$node->nodeValue = "Plugin <strong>".$node->getAttribute('class')."</strong> Not found</div>";
}
}
}
return $dom->saveHTML();
}
Sofar so good, the content is returned but what I get is all the pure text blade markup instead of the Laravel generated html which I want to use.
I think there is a way this could work but I cannot come to think of it.
Try manually building the template by using the method BladeCompiler->compile(), read more here
Edit: I think the facade Blade::compile() will give you access to this function too, just add use Blade at the top of the file.

Post xml to PHP for validation against xsd with XMLHttpRequest or Ajax?

I have a flash application that posts xml to a php page which validates it against an xsd schema. I'm trying to do the same thing but from an html page. I'm using XMLHttpRequest or with jquery's ajax call but I keep running around the same issues. "document has no document" or the "access-control-allow-origin' header issue. I can fix one but not the other.
My PHP page looks like this:
function libxml_append_errors() {
global $returnXML, $errors;
$e = libxml_get_errors();
foreach ($e as $error) {
$en = $returnXML->createElement("error", trim($error->message));
$en->setAttribute('line',$error->line);
$errors->appendChild($en);
}
libxml_clear_errors();
}
libxml_use_internal_errors(true);
$xml = new DOMDocument();
$contents = $HTTP_RAW_POST_DATA;
$xml->loadXML($contents);
$returnXML = new DOMDocument("1.0", "utf-8");
$rootNode = $returnXML->createElement("result");
$returnXML->appendChild($rootNode);
$errors = $returnXML->createElement("errors");
if (!$xml->schemaValidate('muffin_dumplings.xsd'))
{
libxml_append_errors();
}
$rootNode->appendChild($errors);
echo $returnXML->saveXML();
Either way I'm looking to get xml back with any validation errors or a simple empty error xml node same as I do with flash.
If anyone cares, here is the answer. When you post to PHP, have the right headers, and are using ajax you need to pass a content type. Then it works.

How i can validate the DOMDocument load function wheather it is working or not

Am working with feeds parsing Using Dom Document.
$url = 'http://www.blogxxx.com/feed';
$rss = new DOMDocument();
$rss->load($url);
How to validate wheather my load function loaded the passes url or not,if url is going down it keep processing.
Any solution other then
$loadUrl = $rss->load($url);
if($loadUrl){
}else{
echo 'Url Seems to be down';
}

PHP DOMDocument - trouble accessing list index

I am writing some code for an IRC bot written in php and running on the linux cli. I'm having a little trouble with my code to retrieve a websites title tag and display it using DOMDocument NodeList. Basically, on websites with two or more tags (and you would be surprised how many there actually are...) I want to process for only the first title tag. As you can see from the code below (which is working fine for processing one, or more tags) there is a foreach block where it iterates through each title tag.
public function onReceivedData($data) {
// loop through each message token
foreach ($data["message"] as $token) {
// if the token starts with www, add http file handle
if (strcmp(substr($token, 0, 4), "www.") == 0) {
$token = "http://" . $token;
}
// validate token as a URL
if (filter_var($token, FILTER_VALIDATE_URL)) {
// create timeout stream context
$theContext['http']['timeout'] = 3;
$context = stream_context_create($theContext);
// get contents of url
if ($file = file_get_contents($token, false, $context)) {
// instantiate a new DOMDocument object
$dom = new DOMDocument;
// load the html into the DOMDocument obj
#$dom->loadHTML($file);
// retrieve the title from the DOM node
// if assignment is valid then...
if ($title = $dom->getElementsByTagName("title")) {
// send a message to the channel
foreach ($title as $theTitle) {
$this->privmsg($data["target"], $theTitle->nodeValue);
}
}
} else {
// notify of failure
$this->privmsg($data["target"], "Site could not be reached");
}
}
}
}
What I'd prefer, is to somehow limit it to only processing the first title tag. I'm aware that I can just wrap an if statement around it with a variable so it only echos one time, but I'm more looking at using a "for" statement to process a single iteration. However, when I do this, I can't access the title attribute with $title->nodeValue; it says it's undefined, and only when i use the foreach $title as $theTitle can I access the values. I've tried $title[0]->nodeValue and $title->nodeValue(0) to retrieve the first title from the list, but unfortunately to no avail. A bit stumped and a quick google didn't turn up a lot.
Any help would be greatly appreciated! Cheers, and I'll keep looking too.
You can solve this with XPath:
$dom = new DOMDocument();
#$dom->loadHTML($file);
$xpath = new DOMXPath($dom);
$title = $xpath->query('//title')->item(0)->nodeValue;
Try something like this:
$title->item(0)->nodeValue;
http://www.php.net/manual/en/class.domnodelist.php

iOS app using PHP XML based web API

I am fairly new to iOS development and trying make a simple app which will communicate with PHP API. Data request and response will be in XML format only..
this is my php method for login,
function login()
{
$mainframe = JFactory::getApplication();
$xmlcnt = array();
if (!isset($HTTP_RAW_POST_DATA))
{
$HTTP_RAW_POST_DATA = file_get_contents("php://input");
}
if(empty($HTTP_RAW_POST_DATA))
{
$xmlcnt['code'] = "2";
return $xmlcnt;
}
$doc = new DOMDocument();
$doc->loadXML( $HTTP_RAW_POST_DATA);
$login_data = $doc->getElementsByTagName( "data" );
foreach( $login_data as $login )
{
$user_nm = $login->getElementsByTagName( "username" );
$user_nm = $user_nm->item(0)->nodeValue;
$password = $login->getElementsByTagName( "password" );
$password = $password->item(0)->nodeValue;
} ......
and the xmldata look like this "<data><username>testuser</username><password>password</password></data>"
i want to understand how/what should i use in xcode objective-c to send and recieve XML efficiently.
Thank you verymuch
you can check an XML parser for that, here some examples: http://cocoawithlove.com/2011/05/classes-for-fetching-and-parsing-xml-or.html
If you are asking which xml parser to use, Writing your own parser should help a lot in performance. We usually add data compression to keep size of data transfer low. We use simple zip library and also do encryption is needed. Zipping will help a lot if the data size is large

Categories