Fixing PHP’s ‘Warning: simplexml_load_file(): I/O warning : failed to load external entity’

Today I had to re-visit a Drupal module I wrote in 2015. The module parses an external XML file which it loads using simplexml_load_file. When I opened the version of the site that lives in my local server, and visited the page that uses the module, I got the error in the title of this entry. I checked php.ini to make sure allow_url_fopen was On. It was.

Searching the web I came to a bug report in the php website. It was suggested to restart the apache server since the contents of resolv.conf may have changed after the server, and php got their DNS servers entry. This made sense to me, since I have switched networks since turning the computer on. I gave it a try, and it worked:

service httpd restart

Other info:

  • The location of php.ini in my case, running Fedora with php installed using dnf, is /var/php.ini
  • The location of resolv.conf is /etc/resolv.conf

The sources I visited:

Advertisements

Fixing Error Code 32 when Using the Twitter API

Yesterday, I started working with the twitter API. It’s been a long time since I did anything with it, and now that it uses Oauth, I found that it is a bit less intuitive, but after a couple of times you get used to validating requests, and to the tedious signing process. However, I noticed that some of my requests were failing with an error code of 32. This is the actual message I got as response:

{“errors”:[{“message”:”Could not authenticate you”,”code”:32}]}

This message is really useless considering there are many reasons why your authentication could be failing. By looking at that error message all you know is that you could not be authenticated, but you don’t know why. The reasons, as it turns out, are not as intuitive as you may think.

When someone tells you that you could not be authenticated, your first thought is to consider whether you have the right credentials. But once you’ve verified that you do, what other options do you have? Well, it could be that the signature is incorrect because you did not order the parameters in the right order. It could also be that your server is using a different timezone. Who would ever think of these as reasons for failing authentication? That is where the message becomes useless.

However, these two instances are pretty much the main reason for failed authentications, so a search will most likely give you a variation of any of these two possible reasons. However, what do you do after you are certain that none of them are the reason? You are pretty much out of luck.

One of the first things I do if something is not going according to plan, is to check that the signature being generated is the same one that twitter generates when using their Oauth Tool. For this you need to know how to modify the timestamp, and the nonce in whatever framework you are using. In mi case, I’m just doing everything by hand, so editing those values is a matter of editing a couple variables. If the signature, the Authorization string, and the signature string coincide with the ones generated by twitter, there should be no reason why your request should fail. However, despite of all 3 matching, my requests were being failed over and over.

The first thing that I noticed that made little sense was that some request were successful, while other were not. This made no sense. Why would twitter fail to authenticate one request, but not another one when both use the same credentials. This is yet another instance of that message being totally useless.

I decided to go over my requests and find out what was different. I noticed that the request that failed were the ones where data was being posted. I was using php’s curl to do the requests, so I decided to go and take a look at the documentation just to make sure I was doing everything right.

I discovered that PHP can take POST parameter in two ways when using curl. The first one is a string of key value pairs separated by ampersands:


key1=val1&key2=val2

The second one is using an array:


array (
  'key1' => 'val1',
  'key2' => 'val2'
);

Well, it turns out that if you use an array, php will set the Content-Type header to multipart/form-data, but then twitter will fail to authenticate you. Although the reason for failing the request may be an acceptable one, the message you get back is not, because it gives you no indication whatsoever as to why the request failed.

Next time you encounter that error code 32, remember to check you headers as well as your data, along with the server timezone, the order of your parameters when building the signature string, and you may as well check that you are not wearing anti-twitter outfit, just to be sure twitter will not deny your request because of that too.

Web Scraping with PHP

Web scraping is an interesting thing to do. There is a lot of data on the web, and there are many interesting things that can be done with it if it is scraped and organized in more meaningful ways. There are many ways of scraping data, and you may choose the one that is best for what ever it is you are trying to do. From the simplest of ways, manually copy and pasting, to the more complex such as automatic link following and computer-simulated human interaction, web scraping is useful, interesting and fun.

Imagine you want to study plane ticket prices and how the fluctuate over time.You may want to just bookmark the site, and visit every day. Copy the price and paste it into a spread sheet. This is OK since you only need to get a price and you could set some kind of reminder to make sure you don’t forget to do it. But what happens when you want to get price for the same ticket but different travel agencies, or even different airlines? Lets say you want to compare 100 different agencies. Now copy and paste doesn’t seem like a good idea.

A few days ago I had to gather information on car dealers from a site that allowed you to find car dealers near you based on your zip code. I had to run all the US zip codes, and get all the information into a database. That definitely didn’t sound like something I wanted to do with copy and paste, so I did what programmers do best: let the computer do the work.

I think many programmers will agree when I say that programmer are inherently lazy. I’m not talking about programmers spending all the time like a couch potato, because in fact many programmers work day and night. What I mean is that we like to do as little work as possible to accomplish a task. That is why we program in the first place, because we want to automate tasks so that we don’t have to bother ourselves with repetitive tasks.

So, how do you program a web scraper? There are many ways to do it, but the basic idea is always the same: fetch a resource from the net, usually a web page, analyze the code searching for the data that is relevant to you. Save that data somewhere. That is all you really need to know to start scraping data. So, lets build a simple web scraper in php.

Before continuing, I’d like to mention that there are scraping solutions already made. There is software for scraping data, and there are libraries written for many languages that specialize on data scraping. However, for the sake of learning, we are going to code our scrapers here by hand.

What do we need?
We need php, and a way to interact with the DOM. If you read my previous entry where I talk about php and the DOM, you know of a few options to do that. We will also need an idea of what we want to scrape. Lets start with something simple. We will scrape the box office information from IMDB. We will only do it this one time, but in a real life situation you may want to set a cron job to scrape the data daily, weekly or at any other interval of time.

The first thing we need to know is the URL of the page from which we want to scrape the data. In this case it is http://www.imdb.com/chart/
Then we need to know how to find the data in which we are interested. For that, since we are going to be using the DOM, you can just look at the source code of the page. You will notice that the information that we want to scrape is in a tr element with a class name of either chart_odd_row or chart_even_row. That is what we will use to identify the information.

Now, let the fun begin.

Crete a file called box_office_scraper.php. I placed it inside a directory called IMDB. Open the file on your favorite editor, and get ready to type.

First, lets get the document from the web:


$url = "http://www.imdb.com/chart/";
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$document = curl_exec($curl);

echo $document;

We declare a variable to hold the url of the document we want to fetch.
Then we initialize curl, passing in the url.
We set the CURLOPT_RETURNTRANSFER option so that curl returns a string containing the document rather than printing it.
Then we execute curl, and save the returned string in a variable.
Finally we echo the contents of the variable just to make sure we got everything right. You should now be seeing the same thing you would see if you visited the url directly. We echo the contents just to verify, but we don’t really want to echo the contents, so you can now delete that echo line.

Now that we have the document, it is time to search for the data we want, but first we need to create a DOM representation of the document we have. Continue editing you file:


$dom_rep = new DOMDocument;
$dom_rep->loadHTML($document);

If you reload your page now, you should no longer see the page that you were seeing before (provided you deleted the echo). Depending on your php configuration, you may, however, see a bunch of warnings. That is because the document is malformed. Personally, I prefer to turn those warnings off in this case. Usually, I like to have all error and warnings visible, so I can find ways to get rid of them by fixing whatever is causing them, but in this case those warning are only polluting my page. If you want to get rid of the warnings, just add this line at the top of the document, right after the opening php tag:


error_reporting(E_ERROR);

This way you tell php to only report errors. We want to be able to see when something goes wrong.

Now that we have a DOM representation of the document, we can start working with it. Since we know the data we want is in tr elements, we can just grab them all and see if they have the class names we are looking for. Unfortunately, the DOM library that comes with php has no way to get elements by class name, so we will have to write our own.


$all_trs = $dom_rep->getElementsByTagName('tr');
$trs_we_want = array();
foreach ($all_trs as $tr) {
  $class_name = $tr->getAttribute('class');
  if (preg_match("/chart_(even|odd)_row/", $class_name)) {
    $trs_we_want[] = $tr;
  } 
}

We wrote a simple loop, but we could have written a more robust function. In this case the loop is enough.

Now that we have all the elements we need, we can proceed to get the data. One thing to notice is that we will get 30 tr elements, but we are only interested in the first 10. We get 30 because we also get the ones from the other two tables in the page.

Lets loop our elements up to the 10th and get the data:


for ($i = 0; $i getElementsByTagName('td');
  $the_tds_arr = array();

  foreach ($the_tds as $td) {
    $the_tds_arr[] = $td;
  }

  $movie_title = $the_tds_arr[2]->nodeValue;
  $rank = $the_tds_arr[0]->nodeValue;
  $weekend = $the_tds_arr[3]->nodeValue;
  $gross = $the_tds_arr[4]->nodeValue;
  $weeks = $the_tds_arr[5]->nodeValue;
  echo "
"; echo "

$movie_title

"; echo "Rank: $rank
"; echo "Weekend: $weekend
"; echo "Gross: $gross
"; echo "Weeks: $weeks
"; echo "
"; }

As you can see, we are only looping and getting the data that we want. We created the $all_tds_arr array because we cannot access the $all_tds as an array. We could have used more DOM, but the idea here was to keep it as simple as possible. In this example we are only printing the info on screen, but on a real life situation you may want to save it to a file, a database, or a spreed sheet, or some other kind of back end that you have.

Here is all the code:


error_reporting(E_ERROR);

$url = "http://www.imdb.com/chart/";
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$document = curl_exec($curl);

//echo $document;

$dom_rep = new DOMDocument;
$dom_rep->loadHTML($document);

$all_trs = $dom_rep->getElementsByTagName('tr');
$trs_we_want = array();
foreach ($all_trs as $tr) {
  $class_name = $tr->getAttribute('class');
  if (preg_match("/chart_(even|odd)_row/", $class_name)) {
    $trs_we_want[] = $tr;
  }
}

for ($i = 0; $i getElementsByTagName('td');
  $the_tds_arr = array();

  foreach ($the_tds as $td) {
    $the_tds_arr[] = $td;
  }

  $movie_title = $the_tds_arr[2]->nodeValue;
  $rank = $the_tds_arr[0]->nodeValue;
  $weekend = $the_tds_arr[3]->nodeValue;
  $gross = $the_tds_arr[4]->nodeValue;
  $weeks = $the_tds_arr[5]->nodeValue;
  echo "<div>";
  echo "<h2>$movie_title</h2>";
  echo "Rank: $rank<br />";
  echo "Weekend: $weekend<br />";
  echo "Gross: $gross<br />";
  echo "Weeks: $weeks<br />";
  echo "</div>";
}

On the next post we will see how we could use the libraries we talked about in the past for working with the DOM to make scraping easier.

DOM and PHP

My first programming language was javascript, and the book that made me first realize that I wannted to program for a living was DOM scripting from publisher Friends of ED. Back then I thought javascript was all about DOM manipulation, and honestly, back then it was. Now, javascript has become a more respected language and has found its place as the king on the realm of client side programming, and it has made its way to the server end. But DOM manipulation is still a need. For better or worse, the DOM doesn’t seem to be going away any time soon.

Just this week I’ve been working with the DOM, but this time in php. So how is it like to work with the DOM in php? While this is not my first time working with the DOM in php, I must say that it feel wierd. I think PHP + DOM is not a natural combination, but it works well none the less.

When you want to work with the DOM in PHP, you have a few options. I’ve found that the PHP library is enough, but maybe not the most comfortable way. It is what I use anyway, but that is because I only needed to interact with the DOM very little, if you need heavy DOM interaction in PHP, I would recommend you look at some of these projects:

htmlSQL: htmlSQL is a very simple php class that makes it really easy to navigate the DOM using SQL-like syntax. The project has been abandoned, but if you just need to do some interaction with the DOM, it should be enoug. Optionally, if you really like the project, you could fork it and continue its development.

Simple HTML DOM: This is another options. It follows a more OOP approach to navigating the DOM, and it has fetures that the PHP DOM library lacks, like the hability to pass in a URL and get the DOM representation of that resource. If you want to do that with the PHP DOM library, you would need to first fetch the document using something like cURL, and then load the HTML into the DOM object.

PHPQuery: This is probably the most interesting project. It is ispired by jQuery, so if you are familiar with jQuery, you will love phpQuery. Do not expect, however, to find function like fade or animate, they would not make sense on the server side where there is no visual representation of the DOM. You can ofcourse make animations on the server side, but that would just be silly.

Next time I will show you how to build a simple web scraper with php, and we will use these libraries, and the PHP DOM library and see which one is the easiest to work with.

Fixing Call to Undefined Function mcrypt_module_open PHP

While working on a Magento-based store, I cam across this error:

Fatal error: Call to undefined function mcrypt_module_open() in /path/to/Magento/site/lib/Varien/Crypt/Mcrypt.php on line 63

I had never encounter this error before, so I did a quick search, and found out that the problem was a missing module on php. The missing module was mCrypt.

Running phpinfo() confirmed that the module was not installed. Once I knew that, it was just a matter of installing that module, and restarting the apache server.

To install mCrypt on Ubuntu is very simple:

sudo apt-get install php5-mcrypt

And to restart apache:

sudo /etc/init.d/apache2 restart

This solves the problem.

Useful sources:
http://techwhet.jduy.com/2009/09/ubuntu-php-mcrypt-installation.html
http://ubuntuforums.org/showthread.php?t=698084

Double or Single Quotes on preg_replace ?

Today I run into a curious issue while implementing payment processing via authorize.net on a website. The issue has nothing to do with the website or authorize.net, but rather with php.

On the website, users ca chose a donation option. This options have values like “Donation Option – $50”. I have to submit them like that because that value needs to be passed to authorize.net as a custom field, but in order to capture the monetary value, I need to parse that string. At some point I end up wit just the number, and the sign (ej: $50). At this point it is just a matter of removing the sign from the number, so I do this:

preg_replace("/\$/", "", $money);//$money holds the value, in this case "$50"

But that does not work. Inspecting a bit further I realize what the problem is:

preg_replace("/\$/", "B", $money);// gives back "$50B"

this means, that piece of code is actually being interpreted as:

preg_replace("/$/", "B", $money);

so the $ is not being escaped, and we are loosing / at some point. So I decided to do a little duckduckgoing (that is like googling, but for duckduckgo.com), and I find this form discussion:

http://board.phpbuilder.com/board/showthread.php?t=10124101

Let’s try it out:

preg_replace("/\\$/", "", $money);//gives back 50.

This works!, but why? Well, the fact that this works means we need to escape the \ as well in order to be able to scape the $. What about something a bit different:

preg_replace('/\$/', "", $money);//gives back 50

This works too! At this point I remember that in php strings are treated differently depending on how you quote them. You can read more about it on http://www.php.net/manual/en/language.types.string.php

So, I conclude that this problem has to do with string expansion, and that is is better to use single quotes (‘) instead of double quotes (“) when working with regexps in php.

Back References in PHP: How to Create Variable Variables Using Them

I found and interesting problem today. I am working on a wordpress plugin and I wanted to use some sort of template to display the results of a search. I came out with a nice solution that would let me use some text wrapped around % and %. This should be replaced by some variable value. Since I wanted the template to be future proof, I did not want to do something like:

$template = preg_replace(‘/%name%/’, $name);
$template = preg_replace(‘/%last%/’, $last);

but rather, I wanted something that would “guess” the variable names from the text to be replaced. This seemed like an easy thing to do. The first thing I thought was backreferences.

The idea was that if I created a variable variable from the backreference I would be able to accomplish the job. However, it was not that easy.

This is what I have.

I have a function that takes an argument. This argument is an array of arrays containing the data to be placed in the template. A simplified version of the array would look like this:

array(
  [0] = array(
    [name]="John",
    [last]="Smith",
    [phone]="(123)123-1234"
  ),
  [1] = array(
    [name]="John",
    [last]="Smith",
    [phone]="(123)123-1234"
  ),
  [2] = array(
    [name]="John",
    [last]="Smith",
    [phone]="(123)123-1234"
  )
)

so, that is what the function would receive. The function looks like this:

function templating($data){
  foreach($data as $d){
    extract($d);
    ob_start();
    ?>
    <p>
      Name: %name% %last%
      <br />
      Phone: %phone%
    </p>
    <?php
    $mkp = ob_get_contents();
    ob_end_clean();
    $mkp = preg_replace('/%(.+?)%/', $"$1", $mkp);
    echo $mkp;
  }
}

Well, this doesn’t work. It turns out you cannot create a variable variable out of the backreference like I tried to do there. After some failed attempts to create a variable variable out of a backreference, I tried something different.

Before we continue, if you don’t get it. Let me explain the thoughts that led me to write the code up there.

Since I have the array structured showed earlier, I thought I could extract the values into their own variables and reference them in the replacement. The commented code might help you understand better, (and maybe even me in the future when I forget all this XD)

function templating($data){
  foreach($data as $d){
    extract($d);
    //at this point I have individual variables holding the data for each loop run
    //so, for the first loop I have:
    //$name = "John"
    //$last = "Smith"
    //$phone = "(123)123-1234"
    ob_start();
    ?>
    <p>
      Name: %name% %last%
      <br />
      Phone: %phone%
    </p>
    <?php
    $mkp = ob_get_contents();
    ob_end_clean();
    $mkp = preg_replace('/%(.+?)%/', $"$1", $mkp);//the regexp matched %name%, %last%, %phone%, and returned name, last, and phone as backreference values.
    //I thought I could create a variable variable using $"$1", since that would
    //become $name, $last, and $phone, but that is not what happens.
    echo $mkp;
  }
}

I decided to take a look at preg_replace_callback.

I rewrote the function like this:

function templating($data){
  foreach($data as $d){
    extract($d);
    ob_start();
    ?>
    <p>
      Name: %name% %last%
      <br />
      Phone: %phone%
    </p>
    <?php
    $mkp = ob_get_contents();
    ob_end_clean();
    $mkp = preg_replace_callback('/%(.+?)%/', function($m){
      global ${$m[1]};
      return ${$m[1]};
    }, $mkp);
    echo $mkp;
  }
}

But that didn’t work either, although it was closer.
I kept on modifying the function a bit more, and came out with this:

function templating($data){
  foreach($data as $d){
    ob_start();
    ?>
    <p>
      Name: %name% %last%
      <br />
      Phone: %phone%
    </p>
    <?php
    $mkp = ob_get_contents();
    ob_end_clean();
    $mkp = preg_replace_callback('/%(.+?)%/', function($m){
      extract($d);
      return ${$m[1]};
    }, $mkp);
    echo $mkp;
  }
}

This did not work either, but it gave me a clue of why the previous function hadn’t worked. I thought that since the callback was within templating, it would have access to the variables, but it did not. Then I made $d global in the callback, but it still didn’t work. So I figured that it was not accessing the variable. I finally made $d global in templating, and that worked. Note that we declare $d global before the loop, otherwise the $d declared in the loop will be overwritten by the global declaration of $d.

The function ended up like this:

function templating($data){
  global $d;
  foreach($data as $d){
    ob_start();
    ?>
    <p>
      Name: %name% %last%
      <br />
      Phone: %phone%
    </p>
    <?php
    $mkp = ob_get_contents();
    ob_end_clean();
    $mkp = preg_replace_callback('/%(.+?)%/', function($m){
      global $d;
      extract($d);
      return ${$m[1]};
    }, $mkp);
    echo $mkp;
  }
}

This way I was able to accomplish the goal, and I got a pretty nice templating system. Now I can even move the HTML into a template file and load that template file instead of having the markup in the functions. Why would I do that? Because that keeps the code cleaner and makes it easy to edit the template without touching the function, which is always a good thing.

I was curios about why the very first attempt did not work, so I asked a question on one of those Q&A sites, you can follow it here: http://programmers.stackexchange.com/questions/133685/is-it-possible-to-create-a-variable-variable-from-a-back-reference-in-php

I also found this page useful since I didn’t remember how to get the backreferences in php:
http://stackoverflow.com/questions/4694169/how-to-use-backreferences-in-php

And finally, if you want to read more about variable variables, you should read:
http://www.php.net/manual/en/language.variables.variable.php

Solving the Lack of Comma Operator in PHP

This is somehow a follow up of my previous post Making Decisions Inside Function Calls

As I continued developing I hit yet another problem. How do we execute more than one expression inside the ternary operator?

When you are developing there are times when you want to be able to do stuff like this:

if(condition){
  func();
  func2();
}else{
  someotherFunc();
}

this is something I’m sure you’ve encountered many times. In my case, I’m using CORE. Most CORE functions expect a string as their first parameter. For example:

div(
  'this is the content of the div'
);

and most functions return a string too!, so we can do something like this:

div(
  p('this is a paragraph')
);

the p function returns a string that has the text we passed to it wrapped in <p></p> tags. This is a pretty smart think to do because we can nest function calls like this:

div(
  h1(
    spam(
      a(
        'Introduction', '#nogo'
      )
    )
  )
  .p(
    'Hello there, my name is '
    .strong('Buzu')
    .' nice to meet you.'
  )
)

It is a really nice way to develop websites. And when we add the ability to make decisions inside the function calls as we saw in the previous post, this becomes really powerful. But what happens when you want to do more than one expression?

If php had a comma operator, you would do something like this:

div(
  condition ?
    expression_1, expression_2, expression_3
  :
    expression_4, expression_5
);

However, if you do that in php, all you will get is an error.

It was suggested to me to use a lambda. At first I thought it was a nice idea, and felt stupid for not thinking about it myself, but then I quickly remembered why that was out of the question:

div(
  (condition ?
    function(){
      expression_1;
      expression_2;
      expression_3;
    }
  :
    function(){
      expression_4;
      expression_5;
    }
  )
);

After the conditional is evaluated, you end up with something like this:

div(
  function(){...}
);

And that throws you an error because the function cannot be converted into the string that div expects.

So, there is our problem.

The solution can be quite easy depending on what you are trying to do. In my case, the expressions are just function calls (I guess they are not really expressions, but lets just think they are). We already know we can execute as many function calls as we want as long as they return a string so we can concatenate them as a single string which is the parameter that we are expecting. That is why this is possible:

div(
  p('text')
  .p('text')
  .p('text')
  .p('text')
);

But sometimes we want to execute some other arbitrary functions, maybe functions that take care of some setup that is necessary before we can start using some other functions. For example, if you are developing a wordpress theme, sometimes you need to call functions that take care of populating global variables that are used by some other functions like the_author(). So we want to create something like this:

div(
  have_posts() ?
    the_post() //takes care of setting up some info that we will need next
    loadFunction('the_author')
  :
    ''
);

If you try that out, you will get an error. there is no way to insert those two function calls inside the ternary operator. At least no way that I’m aware of. The solution would be to concatenate them so they become one single expression. But you should not just concatenate them,since you don’t know what kind of stuff you could get back from the_post() now or in the future. You could end up with some weird result like:

‘1 Buzu’
or
‘Array() Buzu’

What you want to do is execute the_post() but mute it’s output whatever it might be.

Fortunately we have buffers in php. So the solution could be as simple as doing:

div(
  have_posts() ?
    mute('the_post') //takes care of setting up some info that we will need next
    .loadFunction('the_author')
  :
    ''
);

In theory, this should solve the problem. The mute function would be simply something like this:

function mute(func, args=array()){
  ob_start();
  call_user_func_array($func, $args);
  ob_end_clean();
  return '';
}

I have not tested this. It is just a theory that I will test later, but I think it should solve the problem.

There are still more problems to solve. For example, what if you want to do this:

div(
  condition ?
    $a = $b + $c;
    func($a);
  :
    func()
);

I think this problem could be harder to solve, and it might be just better to let some of the logic happen outside function calls.

What do you think?

Making Decisions Inside Function Calls

I am currently actively developing using CORE. CORE is a library I’m writing to simplify the tedious process of writing HTML. Instead of doing this:

<div class="wrap">
  <p>Hello There <a href="somePage.html">read this</a></p>
</div>

You can do this:

div(
  p(
    'Hello There'
    .a('read this', 'somePage.html')
  )
  ,'wrap'
);

I really find it more pleasing to write that kind of code than writing markup, and I’ve seen an increase on my productivity due to the fact that I have to write less code, the end result is easier to read, it is easy to divide the page in functions that display different sections of the page. For example,you can do this:

div(
  theContent()
  .theComments()
);

theContent() is a function that returns the markup for the content of the page, and theComments() does the same for the comments section of the page. There are many other benefits, like the fact that I no longer need to worry about closing tags in the right order, or making sure all tags have a matching closing tag.

There is, however, one problem that was driving me nuts. Quite often you want to write something or other depending on some parameters. For example, if you are developing a wordpress theme, you might want to display some alternative text when there are no comments to show on a page. The usual way to do that would be:

if(have_comments()){
  //code here to show the comments
}else{
  ?><p>There are no comments to display</p><?php
}

But how do you do that with CORE?

One way would be to manage your logic outside the function call:

if(have_comments()){
  $comments = //code to show the comments
}else{
  $comments = p('There are no comments to display);
}

div(
   theContent()
   .$comments
);

But there are sometimes when you just want to handle the logic inside the function call. I can’t remember how many times I said “I wish I could just handle that inside the function call instead of having to create an extra if”.

Well, today I got an Idea. It istarted with a simple

alert(1==2 || 'b');// this is javascript

which then became

alert((1==1 ? 'b' : 'c') + ' yep');//still javascript.

Then I decided to take that idea into php. I think that was the best thing that I did today. Now I can do something like this:

div(
        h4('What people are saying')
        .(have_comments() ?
                '<ol id="comment_list">'
                .loadFunction('wp_list_comments')
                .'</ol>'
        :       
                'There are no comments to display. Add yours'
        )
        .br()
        .loadFunction('comment_form')
        ,'two_third'
);

Don’t mind the loadFunction() calls, they just “trap” the output of functions that do not return their result, but print it. What is important here is to notice the ternary operator, which makes handling the logic inside the function call possible.

What do you think about this? Personally, I believe it opens up many new possibilities, especially for people like me, who love working with functions, and who got excited when php 5 started supporting lambdas.

Actualizando php y resolviendo errores con mysql.

Otra vez se llegó la hora de actualizar php. No tanto por que me preocupara que estuviera un poco atrasado, sino por que vanilla forms requiere que el driver pdo de mysql esté funcionando y en mi caso no lo estaba. Ya que para habilitado dicho driver era necesario volver a compilar php, pensé que sería buena idea actualizar php de una buena vez.

Lo primero que hice fue ir al sitio de php y descargar la versión mas nueva (5.3.6), descomprimir el archivo en mi Escritorio y proseguir con la configuración. Para ello hay que cambiar al directorio de php. En mi caso:

cd ~/Desktop/php-5.3.6
./configure [opciones de configuración]

Todo estaba bien hasta que la configuración fallo debido a un error:

Cannot find MySQL header files under yes. Note that the MySQL client library is not bundlCannot find MySQL header files under yes. Note that the MySQL client library is not bundled anymore!ed anymore!

Una búsqueda rápida rebeló que la solución era:

sudo apt-get install libmysqlclient-dev

fuente: http://ubuntuforums.org/showthread.php?t=637973

Una vez hecho eso, todo funcionó de maravilla. Justo ahora make está corriendo y parece que todo está bien.

Si estás pensando en actualizar php, asegúrate de correr phpinfo() primero para que puedas ver tu configuración anterior.Una vez corres la función phpinfo(), en la tabla que se genera, una de las primeras entradas es la configuración con la que la instalación de php que está corriendo fue compilada. Si quieres agregar nuevos módulos, como en mi caso, solo agrégalos junto con tu configuración anterior y de ese modo tu instalación estará como antes, más los nuevos módulos.