Blog

2007 posts (53)

Pages: < Previous 1–10 11–20 21–30 31–40 41–50 51–60 Next >
Ordering: Ascending Descending

1. Strong typing in PHP

2007-12-28 18:20:55 by Martynas Jusevičius

Some time ago David Coallier posted a short example on how to use SPL_Types library to achieve strong typing in PHP. For example, it allows you to define explicit types using classes:

$int = new SplInt(3); 

$float = new SplFloat(3.1412);

Too bad that more examples or documentation are missing, but David mentions he has a tutorial in the works.

An external library is needed since PHP uses weak typing by default. There are some wishes however to have strong typing in PHP 6. It's arguable if PHP would benefit from it (and it would be a major shift in the design of the whole language), but if you prefer making your PHP code more Java-like, you might find SPL_Types useful.

Add a comment Comments (12)

2. Reading Excel files with PHP

2007-12-14 14:39:17 by Martynas Jusevičius

There is a nice tool for reading Microsoft Excel files called PHPExcelReader. It works with .xls files up to Excel version 2003, which are based on the BIFF format (later versions use OOXML). It is written in native PHP and does not require any third-party libraries or the MS Office package.

Looping through all cells in a sheet with PHPExcelReader is as simple as this:

require_once 'Excel/reader.php';

$reader = new Spreadsheet_Excel_Reader();
$reader->setOutputEncoding("UTF-8");

$reader->read("test.xls");

for ($i = 1; $i <= $reader->sheets[0]["numRows"]; $i++)
{
	for ($j = 1; $j <= $reader->sheets[0]["numCols"]; $j++)
	{
		print "\"".$reader->sheets[0]["cells"][$i][$j]."\",";
	}
	echo "\n";
}

Add a comment Comments (1177)

3. PHP 5 features: Class autoloading

2007-12-05 11:46:11 by Martynas Jusevičius

Continuing the series about useful features in PHP 5, another overlooked one is class autoloading. From the manual:

Many developers writing object-oriented applications create one PHP source file per-class definition. One of the biggest annoyances is having to write a long list of needed includes at the beginning of each script (one for each class).

In PHP 5, this is no longer necessary. You may define an __autoload function which is automatically called in case you are trying to use a class which hasn't been defined yet. By calling this function the scripting engine is given a last chance to load the class before PHP fails with an error.

Basically, you get a class name as a parameter in your __autoload() function, and using it you have to figure out the path to the actual class file and include it.

If all of the classes are at known paths in known folders, you might be able to find the class file path using simple string concatenation. However, if the folder structure is more complex, a convenient solution is to have a class name/class file path map (associative array), whether hand-made or generated:

function __autoload($classname)
{
	$classes = array(
		"NotFoundView" => APP_VIEW_DIR."notFound/NotFoundView.class.php",
		"ErrorView" => APP_VIEW_DIR."error/ErrorView.class.php"
		// and so on
	);

	if (array_key_exists($classname, $classes)) require($classes[$classname]);
	// using name as key, get the path and include the file
}

There can be several autoloading functions named differently, but then they have to be registered explicitly using spl_autoload_register(). Class methods can also be used.
These hacks are not very clean, but they help to bring PHP one little step closer to object- and library-oriented approach. For example, a library (such as Propel or DIY Framework) can be implemented with its own class autoloading, and including a single file that handles it will be enough to load the whole library.

Propel 1.3 uses this feature already, and we are implementing it in the new release of the DIY Framework. The framework loader class implements autoload() method, and at the end of the file it is registered using spl_autoload_register(array("DIYFrameworkLoader", "autoload")). Including the loader class effectively loads the whole framework.

Add a comment Comments (5)

4. Relational model does not fit the Web

2007-11-27 18:13:05 by Martynas Jusevičius

Relational databases have been around for decades. They are the most popular and successful form of databases. Also now on the Web, although the concept was created long before the Web emerged.

We feel however that relational model does not fit the Web in several ways, and that application design and implementation using it is not as easy as it should be.

Naming of resources on the Web is hierarchical: domain system, file paths, and URIs all have a common tree structure. On the other hand, the Web is a network from the very core: physical computers, links between Web pages, P2P agents etc. all form giant graphs.

What is more, the content on the Web is very heterogeneous and often semi-structured. There is data-oriented and document-oriented content, and one should be able to mash it together easily and dynamically. That is where XML (also tree-structured) is used and succeeds.

Now, relational model is not good neither at representing tree structures nor graphs, which basically means it is not good at representing the most important structures of the Web. That requires applications to convert between data models before content can be published on the Web, which is time consuming, error-prone, and puts a penalty on performance. Relational schema is very inflexible and virtually cannot be changed on the fly. Have you ever seen a Web application executing ALTER TABLE statements? The instance data cannot be used without a schema, they are tied together, unlike in XML or RDF. For more or less the same reasons, relational databases are not easily decentralized or integrated back together, especially at run-time.

Relational model has already bent over to accommodate XML and RDF, but it should move even more further aside. Semi-structured data in the forms of XML and RDF will further prevail. As will do programming languages such as XQuery that allow coding the whole application without ever leaving the same XML data model.

Researchers at MIT also predict that it is The End of an Architectural Era (It’s Time for a Complete Rewrite).

Add a comment Comments (587)

5. Semantic Web applications go mainstream

2007-11-14 01:23:29 by Martynas Jusevičius

During the last months, a wave of new exciting Semantic Web applications started to appear on the Web:

Twine
A new service that intelligently helps you share, organize and find information with people you trust. Introduction screencast.
Powerset
Natural language search.
True Knowledge
Direct answers to human and machine questions. Introduction screencast.
Freebase
An open, shared database of the world's knowledge. Introduction screencast.

Several of their creators talk in the Web 2.0 Summit - The Semantic Edge presentation.
Most of these applications are so far stealth or invitation-only. It also remains unknown whether they use W3C technologies such as RDF, OWL, or SPARQL. However, this seems like a powerful trend of Semantic Web actually taking off.

Add a comment Comments (53)

6. Android mobile phone platform

2007-11-10 15:38:19 by Martynas Jusevičius

Google has recently announced formation of Open Handset Alliance and development of an open mobile phone platform, called Android. It is rumored to be the platform for GPhone.

A preview version of the SDK will be available to developers on November 12th.

It would be interesting to see how Android compares with other mobile platforms such as Symbian and Embedded Linux. Anyhow, these are exciting times for the smartphone industry as well as software developers.

Add a comment Comments (3308)

7. DIY tips: Multilingual Views

2007-11-09 18:17:08 by Martynas Jusevičius

Using XML as data serialization and XSLT as a templating engine (which DIY Framework does by default), it is pretty trivial to localize your Views for multiple languages.
Simply create an XML file (either one for each specific View or a general one for all the Views) and place it where your XSLT stylesheets can access it. It will contain localized phrases. Each phrase will have a unique identifier and a string value in each of the languages you use. XML has a special reserved attribute xml:lang for identifying the language of the content using language tags. For example:

<phrases>
	<phrase id="insulation">
		<text xml:lang="lt">Izoliacija</text>
		<text xml:lang="en">Insulation</text>
	</phrase>
	<phrase id="mufflers">
		<text xml:lang="lt">Slopintuvai</text>
		<text xml:lang="en">Mufflers</text>
	</phrase>
</phrases>

Then you can access these phrases in your XSLT stylesheet using the filename, phrase ID and a special XPath lang() function:

<xsl:value-of select="document('../phrases.xml')/phrases/phrase[@id = 'insulation']/text[lang($lang)]"/>

Here $lang is the code of the language we want to display our View in. It was defined as a parameter of the stylesheet. In that way we select the localized version of the phrase.
How to retrieve the language code (which will be passed as the value of $lang) is a matter of application design. Probably the simplest solution is to specify a request parameter containing a language code on the Resources you want to localize, e. g. Products/?lang=en. You can also implement an automatic language selection using HTTP content negotiation with the Accept-Language header.

Add a comment

8. Submission bug in Digg?

2007-11-01 15:34:32 by Martynas Jusevičius

You may have noticed, and I have for sure, that submissions from our blog to Digg no longer work. We haven't changed anything on our side, and the URL-encoding in submission parameters was double-checked ant seems perfectly correct. What is most interesting though, that none of our URLs work even when you submit them "by hand" at Digg - Submit Item, no matter that they are perfectly correct and accessible.

Unlikely as it may seem, but I can't help but think that this is a bug on Digg's side. And the only explanation for this behavior I can think of, is that Digg for some reason converts submitted URLs to lower-case before processing them. That doesn't work since our URLs are upper-case and case-sensitive. This kind of behavior would be obviously incorrect, since the path element of an URI is case-sensitive.

Any ideas on this matter?

Add a comment Comments (2)

9. Ohloh, the open source network

2007-10-30 16:19:50 by Martynas Jusevičius

What a great concept has been developed by the guys at Ohloh. It is an open source network that connects people through the software they create and use. If you like developing software and are into social networking as well, this sounds just perfect.
At Ohloh you can find and browse various open-source projects and see who developed them, how they evolved through time, and how much they are estimated to be worth. Ohloh even connects to the CVS/SVN repositories and figures out what languages have been used and who authored what code, line by line! As well as dozens of different kinds of statistics.

We registered our projects as well. They don't look very impressive yet though :)

DIY Framework at Ohloh

DIY Blog at Ohloh

Add a comment

10. Eager fetching and SELECT N+1 problem

2007-10-22 23:33:57 by Martynas Jusevičius

After starting using an ORM and enjoying the benefits it brings, you might soon run into so-called SELECT N+1 problem if you don't use it properly, probably even without noticing it.

SELECT N+1 occurs when you retrieve a collection of objects from database via ORM, and then iterate it accessing the object properties of collection members. For example (we will use Propel):

$posts = PostPeer::doSelect(new Criteria());

foreach ($posts as $post)
{
	$author = $post->getAuthor();
	print $author->getName(); // do something with $author
}

Here we have Post and Author as classes, and each Post has it's own Author (this of course has to be specified as a foreign key in the database schema).
Now, when you access the author of every post in a loop, Propel loads it from the database with a separate SELECT query. And if there were N posts, you get a total of N such queries, plus 1 to load the posts in the first place — thus SELECT N+1.

While such code would work, it is far from optimal, since there is no need to SELECT from database in a loop to get authors of every post. Frequent database queries is one of the biggest hits on backend performance, and SELECT N+1 is causing it but often overlooked. If you are not sure if you have run into this problem, it is easiest to check your database query logs for excessive amounts of alike-looking SELECTs.

The problem is solved using eager fetching, which means that main and related objects are loaded in one go. In other words, when posts are loaded, author for each of them has to be instantiated at the same time, and not later when it is accessed.
The solution is implemented using JOINs and SELECTing data from related tables into one dataset. Processing it into objects (or “populating” objects, in Propel terms) needs little more memory and logic, but that is negligible compared to the overall performance gain. With Propel, it is achieved simply by specifying a different table-specific peer method for loading posts:

$posts = PostPeer::doSelectJoinAuthor(new Criteria());

Add a comment Comments (4)

Pages: < Previous 1–10 11–20 21–30 31–40 41–50 51–60 Next >
Ordering: Ascending Descending