Archive for the ‘php’ Category

Eli White on using lambda functions in PHP

Friday, March 12th, 2010

Eli White offers a very smart use of lambda functions in PHP.

Now not only would this work for my specific situation, but ANY controller could reuse this pagination subview and define exactly how it wanted it’s URLs to be formed. Now, the view could completely change around how the pagination section is displayed, show as many, or as few pages as it wants to, and all that without ever touching the controller.

This is one simple example, but I’ve become enamored of this approach. Using lambda functions in this way, you are able to have complicated logic represented inside of your view, but encapsulated/created by the controller. Also of note is the fact that the view is managing to use the $jsfunc and $baseurl values, but without actually having to be granted access to them. This allows for another level of encapsulation, as I exposed one function, instead of 2 separate variables. In the future if other data points start being needed to determine what a URL should be, the view never needs know that, as the controller will continue to update the function on it’s behalf.

Eli White responds to Fabien Potencier regarding template engines

Sunday, February 21st, 2010

Over on Symfony Nerds, I wrote about Potencier’s ideas about a template engine. I just noticed that Eli White had also written an intelligent reply, well worth reading.

RESTful architectures and Symfony: how big should modules be?

Saturday, February 20th, 2010

I’ve a new post up at Symfony Nerds. In it, I look at the implications of a RESTful architecture for Symfony. Should every module just have 4 actions, read, write, update and delete?

PHP is a sloppy language

Saturday, January 9th, 2010

All programmers should read PHP Must Die. PHP is a sloppy language, with a lot of subtle bugs.

Netbeans is a good IDE for Symfony

Wednesday, January 6th, 2010

I agree with this: Netbeans is a good IDE for Symfony development. I think this is especially true if you, like me, also develop with JVM languages. This last year I was doing some Java/Swing and Groovy projects, so I started using NetBeans again. It has a plugin for doing Symfony work – very handy.

Groovy is an easy step into the JVM world for PHP developers

Saturday, January 2nd, 2010

A script written in Groovy that finds and deletes files that match some given pattern. The syntax of Groovy is wonderfully clean, and not especially foreign to PHP developers. I’d think that if a PHP developer wanted to dive into the world of the JVM, Groovy would make an easy first stop.

The endless quest for the right tools for large scale software

Thursday, December 31st, 2009

Colin Steele writes about the challenges that he and his team are facing at Hotelicopter:

We’ve officially run headlong into one of Ruby on Rails’ deficiencies: programming in the large. We’re not interested in computer science-y solutions, only pragmatic ones.

I’m curious what is excluded by the phrase “computer science-y solutions”? I would normally interpret that to mean “we are looking for well tested solutions with wide deployment” but elsewhere he writes:

We’re currently investigating a spectrum of new technologies in the NoSQL realm, including Tokyo Tyrant, MongoDB, Amazon’s SDB, CouchDB, Voldemort, and more. Tis’ a dizzying mix, and things are popping in the space.

So clearly they are looking at some cutting edge technologies. Colin links to an essay about Programming in the large which includes this:

Maintenance and locality are strong arguments in favor of immutability. The less aspects of an object can be changed, the less you have to worry about the execution history. If an object has a two-phase initialization sequence (e.g. this is so in C++ if you need a virtual function during initialization), you have to make sure that the objects are properly initialized; code that gets handed over such an object will have to check that it’s initialized (if only in an assert()). This all vanishes if the language makes sure that no object remains uninitialized, and doesn’t force a two-phase initialization on programmers like C++. (In C++, the “wrong” design decision was that objects mutate from the base type to the subtype when the various constructors are run. It’s this kind of far-reaching consequences (IOW non-locality) that makes language design an art.) If you take immutability to its extremes, nothing can ever be changed. If you wish to change the world, you write a function that returns a list of changes and let the run-time system inspect that list and execute the proper actions. If you have an interactive program, you emit a list that has a function pointer at its end; the function gets fed the next input and is expected to generation another action list.

In the last few years, many programmers have pointed to mutability as one of main problems they face when they build larger systems. Chas Emerick does a good job of highlighting the problem in his post “All my methods take 316 arguments, and I like it that way

316 arguments to a method (which I don’t think is actually possible in the jvm, but bear with me)? “That’s absurd!”, you’d say. The problem, of course, is that the 3-arg doSomething actually has far more arguments than its signature implies:

The behaviour of every function in a mutable, imperative environment is dependent upon the state of all of the other (variables|attributes|bindings|whatever) in your program at the time the function is invoked.

So, if you have 313 other variables in your program, that 3-arg doSomething is functionally (ha!) operating over 316 arguments.

Would you ever intentionally write a method signature that takes 316 arguments? Would you use any library that contained such a function signature? No? Then why are you using tools that force such craziness upon you?

Chas says “The languages are ready” and he links to some of the major functional languages: Erlang, Clojure, F#, and Fantom. In comments, his readers add in their favorite functional languages: OCaml, Haskell, etc.

One of his readers challenges the idea that functional languages are safer than imperative languages by offering this:

Regarding functions changing state, what about things like this in clojure, Isn’t it like global variables in imperative lang?

(def state (ref #{}))

(defn function that updates state)

(defn another function that updates state)

Chas responds:

You bet. Clojure is not a purely functional programming language, so you can have as much shared state as you want – but the language is going to make you work for those bits of shared state, so you have to “pay” for them. Conversely, imperative languages like Java et al. make you work to achieve immutability, and provide nothing in the way of enabling persistent data structures, etc.

The point is that defaults matter, a lot.

I like the word “default” in this context. In his 2001 book, Effective Java, Joshua Bloch wrote “Favor immutable objects over mutable.” When writing a big system in Java, you work to make your system immutable. In a language like Clojure, the default is just the opposite – you work to make parts of your system mutable.

I have very little experience with functional programming. I am just learning Clojure now (Lisp redone for the JVM). I can not say what benefits its brings. I’m looking forward to learning more in this area. It’ll be interesting to see where functional programming comes to be regarded as a “best practice”. Certainly, it will be interesting to see if CTO’s start using these languages at startups, or whether they will be regarded as “computer science-y solutions”.

I’ve somewhat more experience with the web app frameworks that have emerged since 2004. I’m interested in what Colin wrote here:

I suspect as we muddle along we’ll develop a component-level (service level if you prefer) version of the Law of Demeter, which will drive us to make the right decisions for decoupling. I’m not too worried about that. However, we definitely have issues with reuse. Currently the Ruby on Rails state of the art solution for reuse is the gem. Which, let’s face it, is a pathetic solution.

Some of the frameworks seem to encourage bad habits. I’ve already written of Symfony’s weaknesses in Symfony versus The Law Of Demeter: does Symfony promote bad habits?.

When Ruby on Rails first emerged it was targeting web apps, not web services. Rails has a lot of imitators: Groovy/Grails, PHP/Symfony, etc. These all help create web sites, but not necessarily web services. I suspect a new generation of frameworks will be needed to make this kind of work easier:

The place we’re aiming for is a highly decoupled (and scalable), cohesive set of services, joined through REST APIs and/or fully reused common business models.

In their book Restful Web Services the authors Leonard Richardson and Sam Ruby talk about “the human web” and the “programmable web”. This is from page 2:

The Web you use is full of data: book information, opinions, prices, arrival times, messages, photographs, and miscellaneous junk. It’s full of services: search engines, online stores, weblogs, wikis, calculators, and games. Rather than installing all this data and all these programs on your own computer, you install one program – a web browser – and access the data and services through it.

The programmable web is just the same. The main difference is that instead of arranging its data in attractive HTML pages with banner ads and cute pastel logos, the programmable web usually serves stark, brutal XML documents. The programmable web is not necessarily for human consumption. Its data is intended as input to a software program that does something amazing.

Originally, frameworks like Rails were created to help speed the production of sites for the human web. They have evolved since then, Rails in particular. In fact, Richardson and Ruby use Rails for many of the examples they offer in the book, about how to correctly build a RESTful web service. And yet, the scaffolding systems in these frameworks still tend to automate the production of CRUD web pages, rather than PGPD services. (I do not know the state-of-the-art with Rails, so someone can tell me if I’m wrong about its scaffolding.)

Richardson and Ruby suggest that every module (resource) in a RESTful web service should expose just 4 actions:

POST
GET
PUT
DELETE

These are the HTTP verbs, and they roughly correspond to the standard CRUD actions, except that POST is used for both Create and Update, and PUT is used for uploading files:

Create/Update
Read
Upload
Delete

I suspect we need a new generation of frameworks, or at least new scaffolding systems for the existing frameworks, that automate the setup of PGPD services. That seems like the next obvious step forward.

A new post up at Symfony Nerds

Tuesday, December 22nd, 2009

I’ve a new post up at Symfony Nerds. This looks at the evil of utility classes full of static methods, a vice that I’m guilty of on every project. I examine possible ways to refactor the code to get a healthier overall architecture.

Symfony-Check.org: a useful Symfony checklist

Saturday, November 28th, 2009

Just saw this site referenced on the user mailist. Symfony-Check.org is a useful list of things to check when building a Symfony-backed website.

Drupal’s prominence is hurting the PHP frameworks, such as Symfony

Sunday, November 15th, 2009

I’ve a new post up at Symfony Nerds, this one about the extent to which Drupal’s prominence limits the growth of PHP frameworks. I’ve seen a number of Django versus Drupal comparisons, which are a bit unfair, since they compare a framework to a CMS.

Does Symfony promote bad coding habits?

Monday, November 9th, 2009

I’ve a new post up at Symfony Nerds, which looks at some of the bad coding practices which are common on some of the Symfony projects that I’ve worked on.

What would the ideal template system be for Symfony?

Wednesday, October 28th, 2009

I’ve a new post up at Symfony Nerds. Fabien Potencier, the lead developer on Symfony, has recently introduced 2 new components related to templates in Symfony, including Twig, a template engine that will be introduced in Symfony 2.0. I try to offer an overview of the whole debate around these developments.

Traits will bring something like mixins to PHP

Saturday, October 24th, 2009

I’ve a new post up over at Symfony Nerds. It is all about how ‘traits’ will bring something like Mixins to PHP.

A Symfony utility for cleaning up the HTML that users submit

Wednesday, September 16th, 2009

Tom Boutell explains some features that are hidden in his pkToolkitPlugin plugin for Symfony:

* The pkHtml class. Many projects allow users to edit content via a rich text editor. And we all know what happens if the user pastes a Word document in there: the styles of the page wind up hopelessly munged. You can use striptags(), but that doesn’t clean up the CSS, so your page is still a mess.

A common workaround is to use FCK’s “paste as plaintext” mode, which thwarts attempts to paste rich text from another program. That works, after a fashion, but it’s frustrating for users. And none of the workarounds help if the user is actively trying to enter inappropriate HTML in a misguided attempt to re-style their site… then calling you to fix it for the 500th time.

HTML Tidy can do the job, but it has a reputation for being heavy and slow.

Or… you can just use pkHtml::simplify():

How to post data to a remote URL, using PHP

Monday, September 14th, 2009

I have to look this up every time I do it, so I’ll post it here so I can refer back to it easily. The following script is up on Wez Furlong’s website, HTTP POST from PHP, without cURL. He is on the core PHP team. I’m sad to say that he writes:

I don’t think we do a very good job of evangelizing some of the nice things that the PHP streams layer does in the PHP manual, or even in general. At least, every time I search for the code snippet that allows you to do an HTTP POST request, I don’t find it in the manual and resort to reading the source. (You can find it if you search for “HTTP wrapper” in the online documentation, but that’s not really what you think you’re searching for when you’re looking).

Damn, it is a bad sign when folks on the core team are also at a loss. The inconsistency of the PHP language makes it difficult to remember how to do things.

Anyway, here is the script:

function do_post_request($url, $data, $optional_headers = null)
{
$params = array(’http’ => array(
‘method’ => ‘POST’,
‘content’ => $data
));
if ($optional_headers !== null) {
$params['http']['header'] = $optional_headers;
}
$ctx = stream_context_create($params);
$fp = @fopen($url, ‘rb’, false, $ctx);
if (!$fp) {
throw new Exception(”Problem with $url, $php_errormsg”);
}
$response = @stream_get_contents($fp);
if ($response === false) {
throw new Exception(”Problem reading data from $url, $php_errormsg”);
}
return $response;
}

$optional_headers is a string containing additional HTTP headers that you would like to send in your request.

He gives credit to Sara Golemon for much of the work on streams in PHP.

A left join in Symfony/Propel

Friday, September 11th, 2009

I previously mentioned that the worst thing about Symfony is how under-documented Propel is. I also notice that the situation as gotten better than it was in the spring of 2008, when I started using Symfony. There are more and more examples of how to do things, for instance, a Left Join:

$c = new Criteria();
$c->addJoin(PatientPeer::DOC_ID, DocPeer::ID, Criteria::LEFT_JOIN);
$this->patients = PatientPeer::doSelect($c);

All the same, in the future, I will probably use Doctrine. It is well documented.

PHP now has namespaces, closures and late static binding

Wednesday, September 9th, 2009

I guess because this was talked about for so long, I missed the official announcement, but now PHP 5.3 is out, and it supports namespaces, closures and late static binding.

Because this is PHP, all of these are just a little bit uglier than they would be in another language. I’d say that PHP strives to be the ugliest of the high level script languages, but at least it always has Perl to defend it from that accolade.

Check out the syntax for late static binding. This:

public static function test() {
self::who();
}

becomes this:

public static function test() {
static::who(); // Here comes Late Static Bindings
}

Ugly.

Which design patterns does Symfony implement

Wednesday, September 9th, 2009

Alvaro Videla thinks out loud about what design patterns are implemented in Symfony:

Some of the patterns involved in Symfony are:

* Front Controller
* Command
* Intercepting Filter
* Context Object
* Two Step View
* Helper Object or View Helper
* Table Data Gateway (i.e.: ArticlePeer.php)
* Row Data Gateway (i.e.: Article.php)
* Active Record
* Single Table Inheritance

A site converts SQL into Propel code (for Symfony, for instance)

Monday, September 7th, 2009

I think I stumbled upon this site last year, when I was first learning Symfony. At that time, the site was very rough. It is still in alpha, even now, but it looks like it has reached a point where it is useful. It converts SQL into the code needed for Propel.

So it converts this:

person.gender = ‘M’ AND (person.location IN (’Birmingham’, ‘Coventry’) OR person.location = ‘Manchester’) AND (person.enabled <> 0) AND person.age > 16

Into this:

$c = new Criteria();
$crit0 = $c->getNewCriterion(PersonPeer::GENDER, ‘M’);
$crit1 = $c->getNewCriterion(PersonPeer::LOCATION, array(’Birmingham’, ‘Coventry’), Criteria::IN);
$crit2 = $c->getNewCriterion(PersonPeer::LOCATION, ‘Manchester’);

// Perform OR at level 1 ($crit1 $crit2 )
$crit1->addOr($crit2);
$crit3 = $c->getNewCriterion(PersonPeer::ENABLED, 0, Criteria::NOT_EQUAL);
$crit4 = $c->getNewCriterion(PersonPeer::AGE, 16, Criteria::GREATER_THAN);

// Perform AND at level 0 ($crit0 $crit1 $crit3 $crit4 )
$crit0->addAnd($crit1);
$crit0->addAnd($crit3);
$crit0->addAnd($crit4);

// Remember to change the peer class here for the correct one in your model
$c->add($crit0);
$result = TablePeer::doSelect($c);

// This loop will of course need to be edited to work
foreach ($result as $obj)
{
//$val = $obj->getValue();
}

Very useful, since the worst thing about Symfony is how under-documented Propel is.

On future Symfony projects, I may convert to Doctrine.

How do loops work in PHP?

Friday, September 4th, 2009

When I first started to learn how to program I was confused by loops. I will write something short here about how loops work.

Possibly the simplest loop is the “while” loop. It loops while some condition is true.

Let’s suppose we want to get the character count of the first 20 visible words in a block of HTML (this is based on an actual request from a client). Let’s suppose that we are working on a WordPress site, so we will use the WordPress function get_the_content() to get the content:

$contentWithTextAndHtml = get_the_content();

$howManyCharactersHaveWeCountedSoFar = 0;

$howManyWhiteSpacesHaveWeFoundSoFar = 0;

while (20 > $howManyWhiteSpacesHaveWeFoundSoFar) {

$thisCharacter = substr($contentWithTextAndHtml, $howManyCharactersHaveWeCountedSoFar, 1);

if ($thisCharacter == ” “) $howManyWhiteSpacesHaveWeFoundSoFar = $howManyWhiteSpacesHaveWeFoundSoFar + 1;

$howManyCharactersHaveWeCountedSoFar = $howManyCharactersHaveWeCountedSoFar = 1;

}

This while loop is going to continue for as long as $howManyWhiteSpacesHaveWeFoundSoFar is less than 20. Inside of the loop, every time we find a white space, we increase $howManyWhiteSpacesHaveWeFoundSoFar by 1. So after we have found 20 white spaces, this loop will stop running.

We can clean up this code somewhat, using shortcuts that PHP allows. For instance, this:

$howManyCharactersHaveWeCountedSoFar = $howManyCharactersHaveWeCountedSoFar = 1;

can also be written as this:

$howManyCharactersHaveWeCountedSoFar++;

The “++” means “add 1 to this variable”. So we can use this trick to have slightly less code:

while (20 > $howManyWhiteSpacesHaveWeFoundSoFar) {

$thisCharacter = substr($contentWithTextAndHtml, $howManyCharactersHaveWeCountedSoFar, 1);

if ($thisCharacter == ” “) $howManyWhiteSpacesHaveWeFoundSoFar++;

$howManyCharactersHaveWeCountedSoFar++;

}

But our loop isn’t really doing what we want. We want to find the first 20 visible words, so we do not want to count the white spaces that are inside of HTML. If we had simple text, with no HTML, the above loop would work fine. For instance, it would find the first 20 words in this block of text:

“SuperAmazing.com, a subsidiary of Amazing, the leading provider of integrated messaging and collaboration services, today announced the availability of an enhanced version of its Enterprise Messaging Service (CMS) 2.0, a lower cost webmail alternative to other business email solutions such as Microsoft Exchange, GroupWise and LotusNotes offerings.”

but what if we are dealing with a block of text that has a lot of HTML in it, like this:

“<img src=”/images/corporate/logos/super_amazing.jpg” alt=”Company logo for SuperAmazing.com” /> SuperAmazing.com, a subsidiary of <a href=”http://www.amazing.com/”>Amazing</a>, the leading provider of integrated messaging and collaboration services, today announced the availability of an enhanced version of its Enterprise Messaging Service (CMS) 2.0, a lower cost webmail alternative to other business email solutions such as Microsoft Exchange, GroupWise and LotusNotes offerings.”

Let’s suppose we need to get the character count (including HTML) out to the 20th word. We will need some simple way to keep track of whether or not a white space is inside of HTML or not. So we could do something like this:

$contentWithTextAndHtml = get_the_content();

$howManyCharactersHaveWeCountedSoFar = 0;

$howManyWhiteSpacesHaveWeFoundSoFar = 0;

$areWeInsideOfHtml = false;

while (20 > $howManyWhiteSpacesHaveWeFoundSoFar) {

$thisCharacter = substr($contentWithTextAndHtml, $howManyCharactersHaveWeCountedSoFar, 1);

if ($thisCharacter == “<") $areWeInsideOfHtml = true;

if ($thisCharacter == ">“) $areWeInsideOfHtml = false;

if (!$areWeInsideOfHtml) {

if ($thisCharacter == ” “) $howManyWhiteSpacesHaveWeFoundSoFar++;

}

$howManyCharactersHaveWeCountedSoFar++;

}

So now we only count white spaces when $areWeInsideOfHtml is false.

If loops confuse you, then you might have trouble figuring out what this line does:

$thisCharacter = substr($contentWithTextAndHtml, $howManyCharactersHaveWeCountedSoFar, 1);

We want to get one character at a time. substr() let’s us get a small section of a string. These are the 3 parameters:

$contentWithTextAndHtml – this is the string we should look inside.

$howManyCharactersHaveWeCountedSoFar – this is where in the string we start to look

1 – this is how many characters we should get. In our, case we just want to get 1 character at a time.

As the code loops, what is basically happening is this:

$thisCharacter = substr($contentWithTextAndHtml, 0, 1);

$thisCharacter = substr($contentWithTextAndHtml, 1, 1);

$thisCharacter = substr($contentWithTextAndHtml, 2, 1);

$thisCharacter = substr($contentWithTextAndHtml, 3, 1);

$thisCharacter = substr($contentWithTextAndHtml, 4, 1);

$thisCharacter = substr($contentWithTextAndHtml, 5, 1);

$thisCharacter = substr($contentWithTextAndHtml, 6, 1);

$thisCharacter = substr($contentWithTextAndHtml, 7, 1);

$thisCharacter = substr($contentWithTextAndHtml, 8, 1);

$thisCharacter = substr($contentWithTextAndHtml, 9, 1);

$thisCharacter = substr($contentWithTextAndHtml, 10, 1);

$thisCharacter = substr($contentWithTextAndHtml, 11, 1);

$thisCharacter = substr($contentWithTextAndHtml, 12, 1);

And so on. You see what is going on here? Each time we loop, we look one character further into $contentWithTextAndHtml, and we get just 1 character. This allows us to eventually get every character in the whole block of text.

But there is still a problem with our code. What happens when we are given a block of text that does not have 20 white spaces in it? What if we get text like this:

“OmniNewsGather is one of our clients.”

That text only has 5 white spaces in it. So this line of the while loop would never stop:

while (20 > $howManyWhiteSpacesHaveWeFoundSoFar) {

We would end up with what is called an “infinite loop”. This is a loop that never ends. Because $howManyWhiteSpacesHaveWeFoundSoFar never equals 20, the loop just keeps going forever. You will be wondering why your code isn’t working.

I recall the first time I wrote an infinite loop. Debugging it was hellish because there were no errors. This is not like getting a syntax error, which ususally tells you what you need to fix. An infinite loop is a subtle, hard to find bug.

If you are lucky, substr() will throw an error which will give you a clue. The error might appear once you start requesting characters that are beyond the end of $contentWithTextAndHtml. For instance, there are 37 characters in this block of text:

“OmniNewsGather is one of our clients.”

So you might get an error once the code does this:

$thisCharacter = substr($contentWithTextAndHtml, 38, 1);

because 38 will be beyond the end of $contentWithTextAndHtml.

What we need to do is put in an extra check, to see if we have reached the end of $contentWithTextAndHtml. So our code would look like this:

$contentWithTextAndHtml = get_the_content();

$lengthOfText = strlen($contentWithTextAndHtml);

$howManyCharactersHaveWeCountedSoFar = 0;

$howManyWhiteSpacesHaveWeFoundSoFar = 0;

$areWeInsideOfHtml = false;

while (20 > $howManyWhiteSpacesHaveWeFoundSoFar && $lengthOfExcerpt > $howManyCharactersHaveWeCountedSoFar) {

$thisCharacter = substr($contentWithTextAndHtml, $howManyCharactersHaveWeCountedSoFar, 1);

if ($thisCharacter == “<") $areWeInsideOfHtml = true;

if ($thisCharacter == ">“) $areWeInsideOfHtml = false;

if (!$areWeInsideOfHtml) {

if ($thisCharacter == ” “) $howManyWhiteSpacesHaveWeFoundSoFar++;

}

$howManyCharactersHaveWeCountedSoFar++;

}

So, what does this line mean?

while (20 > $howManyWhiteSpacesHaveWeFoundSoFar && $lengthOfText > $howManyCharactersHaveWeCountedSoFar) {

In English, this would read as “Loop until $howManyWhiteSpacesHaveWeFoundSoFar equals 20, but only while the length of the text is greater than the number of characters we have counted so far.”

The second part of this while statement protects us against infinite loops. Because now, if we have a sentence like this:

“OmniNewsGather is one of our clients.”

Then the loop will stop after counting 37 characters, even if the code has not yet found 20 white spaces outside of HTML.

When the loop is done running, $howManyCharactersHaveWeCountedSoFar might equal as little as 60 or 70 or it might equal 600 or more, depending on how much HTML there is in the first 20 visible words. For the client, our actual task was to run some tests on the full string that makes up the first 20 visible words:

$shortenedContent = substr($contentWithTextAndHtml, 0, $howManyCharactersHaveWeCountedSoFar);

if (stristr($shortenedContent, “href”)) {
// do stuff here if a link is detected
}

The while() loop is, I think, easy for beginners to get. What is tougher is the for() loop. It is important to realize that the for() loop is totally arbitrary. At some point some programmers decided it would be convenient to take the elements of a while() loop, and write them all on one line. A typical for() loop would look like this:

for ($i=0; $i < count($arrayOfWordPressPosts); $i++) {

$thisPost = $arrayOfWordPressPosts[$i];

// do stuff here with WordPress posts
}

This part of the for() loop simply sets up a variable that we can use to keep count of how many times we have looped:

$i=0

Traditionally, the “i” is suppose to stand for “incrementor”. We will increment it each time we loop. “Increment” basically means “we will add 1 to this variable”.

This part of the loop explains how long the loop should run for:

$i < count($arrayOfWordPressPosts)

Assume that we have an array with 5 WordPress posts in it. The above loop will run until $i equals 5. That is, it will run when i equals 0, 1, 2, 3 and 4, which means it will run 5 times.

The last part of this for() loop statement increments $i:

$i++

This last part is called every time the loop loops. You might ask “Why does this first part, which assigns a zero to i, run only once, but the last part runs every time that the loop loops?” That is a good question. I do not know the answer. This aspect of for() loops has always struck me as completely arbitrary.

The worst thing about Symfony is how badly documented Propel is

Monday, August 31st, 2009

There is a reason why Symfony developers are switching en masse to using Doctrine as their ORM, and that reason is the fact that Propel is badly documented. I’ve been using Symfony/Propel for a year now, and this is the most coherent explanation I’ve yet found about creating OR statements:

It is not a mistake but how propel works. I also thought that writing code like yours I will get an OR but $c->addOr() is when you want to include a rule about the same database field. By default $c->add() will overwrite the previous rules if the first argument (the table field) is the same, thus $c->addOr will make an OR statement for this field. The same is true for $c->addAnd() but you thought it works correct because by default it uses AND between fields, but the purpose of $c->addAnd is when you define different criteria for the same field and you want them connected with and AND. Also why are you using Criterion object directly?

Why does Berkeley think it should be in the business of building its own content management systems anyway?

Thursday, August 27th, 2009

Brad Delong asks “Why does Berkeley think it should be in the business of building its own content management systems anyway?“.

His complaint:

May I say that a content management system that–if you have been off dealing with another crisis in the middle of a task–decides when you come back and try to save your work that you are no longer logged in and dumps you to a login page after which it dumps you not on the page you were working on but on the root page, LOSING YOUR WORK!!!1!!

Such a content management system is HELLSPAWN!! Is WROSE THAN HILTER!1!!!1!…

He is complaining about bspace, which is based on the open-source
Sakai, a content management system written in Java, and focused on the needs of universities.

I think Delong’s post is a good reminder of how infuriating it can be for users when software fails to behave in the ways users expect. I also suspect this is a good example of an issue that users will regard as a bug, but the programmers will see it simply as a potential future feature that they may or may not add (”Should we catch POST info if a user is not logged in?”).

I should add, WordPress has exactly the same problem. Last week I started writing what I thought would be a short post for this blog, but I got carried away by my theme and wrote a long post. Then I went to get some dinner. I left the browser open, with the post unpublished. I came back after dinner and made some more edits, then hit the publish button – and just like that, my work vanished, because while I was out getting dinner, WordPress logged me out (for some reason I’d assumed that the auto-save feature was also refreshing my session info).

One of the nice things about building my own CMS was that I was free to fix the bugs that bothered me most, and this was a big one for me. I added a feature to my CMS that caught any POST info and showed it on screen, even if the person was logged out. This allowed recovery of the post. I worked on my CMS from 2002-2007 and then abandoned it because I could not keep up with projects like WordPress. Nowadays I force myself to use other people’s open source software, because it is economically rational to do so, but I hate some of the choices they make, and some of the features that they fail to implement.

In the comments, Jacob Davies posts this comment, which I thought was very funny and very on point:

Conversation that has happened more times in my career than I care to mention:

Someone else: “How long of a title shall we allow? 32 characters? 64?”

Me: “FOR THE LOVE OF GOD WHY DO WE NEED TO SET A MAXIMUM LENGTH? IS THIS 1952???”

Someone else: “But what if they put in a really long title and fill up the database?”

Me: “THE VERY NEXT FIELD – THE ‘CONTENTS’ FIELD – IS A FREE-TEXT FIELD WITHOUT A LENGTH CONSTRAINT SO IF THEY WANTED TO FILL THE DATABASE THEY COULD DO IT THERE ANYWAY.”

Someone else: “Won’t it waste space if we allow a variable-length string in the title?”

Me: “OH MY GOD YES A TERRIFYING LOSS OF ABOUT 3 BYTES ON A RECORD THAT IS A MINIMUM OF 1024 BYTES LONG AND OFTEN OVER A MEGABYTE, YOU ARE SO RIGHT.”

Someone else: “Yes but every other system has a length constraint for titles.”

Me: “YES AND I SUPPOSE IF EVERYONE ELSE WAS JUMPING OFF A BRIDGE YOU’D DO IT TOO.”

etc

Computer programmers are subject to some kind of strange mental degeneration in which they rate the potential waste of 0.00001% of the capacity of a modern hard disk as more important than the ability to enter titles longer than 32 characters in length.

The Context object in Symfony can cause hassles

Monday, August 24th, 2009

This summer I worked on a project where some other programmer had used the Context object in the model classes. This caused ridiculous problems. For instance, to run the command line tools (such as “symfony propel:build-model”) I had to hard-code the loading of a context object into the core classes – what an ugly hack!

So I was intrigued to read of the problems that the Context object can cause in your form classes, and how dependency injection gives us an easy way to avoid needing the Context object.

You might read that and think “woah, this is getting complicated!” but we’re not talking about dependency injection containers here, we’re simply saying that you can make your form object depend on something to run. The thing it depends on should not be the context singleton, it should be the minimum thing that the form needs to operate correctly – which in this case, is a user object that supports credentials.

…The test here is where we are making this form “dependent” on a user object. In this case we are insisting that the object is an instance of sfUser, which you may argue is tying us in to symfony again, but you could use any test here to ensure that the object will have the necessary functionality you need, maybe check for the existence of a “hasCredential()” method for example.

When writing a test for this form class, we now only need to instantiate a user object and load it with some credentials – much easier than doing the same thing and locking into a context singleton. There may be other times when this form could be useful in a lightweight environment, where you can get speedy access to a user object but don’t want the overhead of the symfony context – you might not think of one now, but it’s best to code this way and you’ll have less reasons to kick yourself further down the line.

How to redirect to original destination after login in Symfony

Sunday, August 23rd, 2009

How to redirect to original destination after login in Symfony. I recall this information was way too hard to find when I first went looking for it:

on first hit to your login action, store referer to the user session:

if(!$this->getUser()->hasParameter(’referer’))
{
$this->getUser()->setParameter(’referer’,$this->getRequest()->getReferer();
}

and then when login succedes, redirect user to stored referer with:

$this->redirect($this->getUser()->getParameter(’referer’);

Left JOINs with Propel in Symfony

Sunday, July 26th, 2009

Here is the stupid, clumsy way that I tried to do a LEFT JOIN in Symfony:

$query = ”
SELECT bailiwick_question.*, count(bailiwick_answer.id) AS howManyAnswers
FROM bailiwick_question LEFT JOIN bailiwick_answer
ON bailiwick_question.id = bailiwick_answer.question_id
WHERE bailiwick_question.end_at > ‘” . date(’Y-m-d h-i-s’) . “‘
GROUP BY bailiwick_question.id
ORDER BY howManyAnswers desc
“;

$connection = Propel::getConnection();
$this->questionStatement = $connection->prepare($query);

$this->pager = new statementPager(null, 10);
$this->pager->setStatement($this->questionStatement);
$this->pager->setPage($request->getParameter(’page’, 1));
$this->pager->init();

Here is the way someone much smarter than I re-wrote the code:

$c = new Criteria();
$c->addJoin(BailiwickQuestionPeer::ID,BailiwickAnswerPeer::QUESTION_ID, Criteria::LEFT_JOIN);
$c->add(BailiwickQuestionPeer::END_AT, date(”Y-m-d h-i-s”), CRITERIA::GREATER_THAN);
$c->addSelectColumn(’bailiwick_question.*’);
$c->addGroupByColumn(BailiwickQuestionPeer::ID);
$c->addDescendingOrderByColumn(’COUNT(bailiwick_answer.id)’);
$questions = BailiwickQuestionPeer::doSelectStmt($c);

A fast Symfony

Monday, May 25th, 2009

A very clever trick for using a portion of the Symfony framework to respond to Ajax calls:

Now I can execute a component from the client side. The component architecture offers native View/Controller separation, and the configuration initialization brings autoloading, database access, and more. It does work perfectly, but is it fast? Speed tests show that not launching the filter chain saves about 40% to 50% of the cost of a symfony initalization. This means that you can multiply the number of requests that your server can handle by two – for very simple requests.

Web 2.0 was such a long time ago

Thursday, May 21st, 2009

I thought the title of this article was funny:

Converting legacy Rails apps to Grails

So now there are “legacy Rails apps”. Sort of makes Rails sounds really ancient. One of the dead languages. You know, Cobalt, Fortran, Rails…

Some bits of simplicity coming in Symfony 1.3

Tuesday, May 19th, 2009

This looks very promising:

I recently introduced the sfFormSymfony class in the 1.3 branch, which includes this pearl of a method:

$form->bindRequest($request);

So clean, so simple. Compare that to the code necessary to do the same thing in the 1.2 branch:

$form->bind(
$request->getParameter($form->getName()),
$request->getFiles($form->getName())
);

Ugly, huh? Fabien’s term was “not ugly, explicit” (I couldn’t help but laugh at his turn of phrase).

Empowering great designers to work freely with the HTML in a Symfony project

Tuesday, May 19th, 2009

I’ve had the good fortune to work with some truly great designers. These are people who are understand the client’s needs, who understand the users, and who naturally develop web sites that feel intuitive to the people who use the site. Long ago I learned that, when working with such designers, it was important to empower them with the code they needed, but to otherwise stay out of the way. In particular, such designers need access to the HTML of the site. When I hide the HTML away inside of PHP functions, I’m limiting the ability of these maestros to perform.

This has implications when working with a framework like Symfony.

A lot of computer programmers would add an image to a Symfony template by using one of the image helpers:

<?php echo image_tag(’banner.jpg’) ?>

But what if the designer needs to add a CSS class to this? What if they are working late at night, and they are unable to reach me? Or they are working in the middle of the day, but it is a day I’m spending away from my computer?

The designers I work with can read PHP code fairly well. And they can look up the image_tag helper and figure out its syntax. But this is a big waste of their time. It takes them further into the world of programming than they should need to go.

When creating URLs in a Symfony project, it is important to use helpers. The helpers take care of figuring out what the right URL should be for things like images. The helpers allow us to develop on one machine and deploy to another server when we go live, and even if that other server has a completely different directory structure, we don’t need to change any links, because the helpers take care of all that for us. However, managing the URLs is the only thing that the helpers should do.

So we do not do this:

<?php echo image_tag(’banner.jpg’) ?>

Instead we either do this:

<img src=”<?php echo $sf_request->getRelativeUrlRoot() ?>/images/banner.jpg” />

or we do this:

<?php sfLoader::loadHelpers(array(’Url’)); ?>
<img src=”<?php echo public_path(’banner.jpg’) ?>” />

This way the URL is managed by Symfony’s helpers, but the rest of the IMG tag is still free for the designers to work with. If a designer needs to add a CSS class, they don’t need to call me on the phone and get me to do it, and they don’t have to start researching Symfony helper tags, instead they just add the CSS class like they always have:

<img class=”header” src=”<?php echo public_path(’banner.jpg’) ?>” />

This is an important bit of project management. It allows for a correct separation of concerns – the designers get to focus on design, and the programmers can focus on the programming.

Binary math and PHP bitwise operators

Monday, May 18th, 2009

A great tutorial about binary math and PHP’s bitwise operators.