Mojalbum.com launch

28 October, 2009 (18:18)

I have updated my showcase page, notice the first item in the list: Mojalbum.com. This web page is not new (it was “born” more than 5 years ago), but our company has bought it earlier this year. And now we have re-realesed it after we have built it from scratch. All that is left is the data (over 4.3 million images), everything else (including the database) is brand new. This is one of the on-going projects so expect to see some related posts in the future.

Some things I learned during the development:

  • Don’t use PHP to import 4 million images (read them from the original DB, store them in the new DB, read the original file and resize it to 4 different sizes and store them in a new location), it is just to slow. The import was running for 1 week.
  • There are tons and tons of useless one-line jQuery “plugins” out there.
  • Don’t care if your JavaScript file is 5 lines long, combine, minify & cache all your JavaScript files so that the browser only needs to make one request to get all the code it needs. Do the same for CSS (haven’t done this for CSS yet).
  • Do research for cool new technologies you could use before you start coding. I missed a wonderful opportunity to use Sass because I found it after most of the CSS was already written.
  • Cache cache and cache!

mojalbum (1)

Change page title with jQuery

14 October, 2009 (15:15)

I just had a need to change the title of the page with JavaScript, and since I use jQuery I imediatelly wrote this:

$( 'title' ).html ( 'new title' );

and it didn’t work. Ok, how about this:

$( 'title' ).val ( 'new title' );

nope. So after some googling I found out that jQuery just can’t do that. You have to use plain old JavaScript:

document.title = 'new title';

I posted this because I think it’s interesting how one gets to rely on a tool he uses, without even thinking to use the technology on which the tool is build, even if that is clearly the better way to go. Or maybe you just get scared of working with the DOM directly if you use jQuery (or something alike) for some time. Don’t get me wrong, DOM is horrid to work with without some abstraction, but sometimes it works beautifully. But jQuery is working really hard to hide the DOM away from you thus subtly seeding fear into your mind.

it’s no coincidence I always think of Doom when I deal with DOM

dom

Setting PHP variables from JavaScript

8 October, 2009 (08:10)

There’s a great deal of forum threads floating around internet where someone is asking “how to set a PHP variable from JavaScript/client”. In most cases the author just doesn’t know how the technology (html, JavaScript, PHP, http, …) he is using works. I’m assuming he somehow thinks that if he will (somehow) set/change a PHP variable from JavaScript that it will change the execution flow of PHP for that request (not that he knows what a request is). The only case where this would make sense is in a Comet application where a PHP scripts pushes data in a infinite loop to the client. But I think it’s safe to assume that someone who is asking this type of questions isn’t developing Comet applications.
There are, off course, valid cases where you might wan’t to change something on the server from the client. What’s important is to realize that that won’t have any effect on the state of the page that the user is currently viewing (until the next request that is). In most cases this would mean setting/changing some session variable or something similar that permanently changes something on the server.
One example of this, that I can think of right now, is if you have some controls on a page that control the font size. You’d want to remember what size the user want’s to use, so that he doesn’t have to set it after every click on your page.
I’m going to list some ways how one might accomplish this. I will not give you any example code, because there is no built-in mechanism for this, it depends on what you wan’t. Also there are two scenarios; you might want to make the change right away or your change can wait until the next request.

AJAX method
This is the most obvious solution. You just make a XHR request to your PHP script, pass it some arguments and the script will do whatever you want it to do. This can be used if you need to make the change right away.

Image/IFrame method
If you, for some odd reason, can’t or don’t want to use AJAX, you can create (using JavaScript) a IMG or IFRAME tag, set it’s “src” attribute to your PHP script and voila. Also used if you need to make the change right away.

Cookie method
If you don’t need to make the change on the server at the moment user does something, you can instead set a cookie (again with JavaScript) and then look for that cookie on every request using PHP and if it is present do something.

URL variable method
This is similar to the “cookie method”. But instead of setting a cookie you append (with JavaScript) some variable to every URL on the current page (excluding external links). Then check for that GET variable on every request with PHP and act accordingly. This one is a little more complex and it has one drawback; if a user doesn’t click on any link after you change them you won’t save his changes on the server.

FORM method/link method
I suppose this one is obvious, if something needs to be changed on the server make a FORM that submits to a script, or make a link that point’s to a script that will change whatever it will change. Off course this method causes a full page refresh. It is, however, the only method that does not require JavaScript.

Pretty textbox jQuery plugin

26 September, 2009 (11:00)

Some time ago I made a pretty search box for our latest project (not yet released) and I thought I’d make it into a jQuery plugin and share it with you. The goal was to have a text input with some default text (search this, or search that) and a pretty magnifying glass image in the right. And when you click (or give focus to) into the input the default text and the image would disappear. This is just an effect we ware going for, you could make something completely different using only CSS and this plugin for the default text disappearing/appearing. The nifty part is that if the user doesn’t enter any text and leaves the input box the default text pops-up again. Best describe this with a image:

pretty text box

Plugin code and demo can be found here. I also played with CSS3 border-radious and box-shadow to make the inputs even more prettier.

update: just realized that the middle label on the image should be “with focus” not “with input”

Conditional CSS

22 September, 2009 (23:14)

CSS is a lovely thing, but it can get out of your hands very quickly (especially if you are programmer first and HTML code-monkey second). I often find myself having some element that appears on various sub-pages of a page, comments for example. HTML is stored in a template file and included where needed and styles, that make the comments pretty, are usually in the main CSS file. No problem with this approach if comments are exactly the same on whichever sub-page they resist. But what happens when they have to be 200px wide on the user’s profile page and 300px somewhere else? You make another CSS file where you override the width and include it on the page.
The problem with this is that you often end up with several CSS files containing a few lines, which increases the number of requests and page load time. But the biggest problem with this is maintainability. All of a sudden you have styles for the same thing in several different files and guess how long that takes to get out of sync.

So I was thinking how one would go about solving this, and I came up with this: what if you ware able to define a certain style only if some condition would be true. CSS if statements! I’m not proposing a juggernaut here, just something along this lines (haven’t really thought about the syntax):

#CommentsContainer {
width: 100px;
background-color: silver;
}
[URL=/some/path/(.*)/([0-9]+)]
#CommentsContainer {
width: 200px;
}
[/URL]
[URL=/some/other/path/([0-9]+)]
#CommentsContainer {
width: 300px;
}
[/URL]

So depending on the URL some of the styles would be defined and some would be not (you could have URL!= for instance and some basic Boolean operators such as AND and OR). You would define the URL with regular expressions (as you have probably guessed).
With this approach you could have all the styles for some page element (comments are just an example I’m struggling with at the moment) defined in one place, which greatly improves maintainability, and you would reduce page load time, which matters the most at the end of the day.

Conditional CSS

I just thought of this and haven’t asked google if somebody has already written about this, so don’t hold it against me if I say that this is my idea.

Be progressive and do community a favor at the same time

24 July, 2009 (19:07)

Currently there are around 5% of internet users that have JavaScript disabled or their browser doesn’t support it. I’m all for progressive enhancement and degrading gracefully,whether you do it or not, depends on you.
I, for one, look forward to the day when this percentage will be zero, and we can all forget about this. Until then I will do my best to keep my web pages friendly to users without JavaScript (I am a prefectionist after all :). If nothing else, search engine’s crawlers are users you simply can’t ignore, and JavaScript doesn’t exist for them.

Sometimes there is a feature that just can’t be done without JavaScript or is to complicated and time consuming that it wouldn’t make sense spending the time to accommodate for that 5% of users. I’ve developed a new strategy for our newest project: if there is a link that triggers some JavaScript code I construct it like so:

<a href=”http://www.our-domain.com/enable-javascript.html” id=”FancyStuffLink”>do some fancy stuff</a>

This is a perfectly valid link that anyone can click. The trick here is that I attach a “onClick” event with JavaScript and remove (or rather replace) the “href” attribute. The end result is that users with JavaScript won’t see the “enable-javascript.html” URL if they hover over the link, and if they click on it the desired functionality executes.
Whereas users with JavaScript disabled are (upon clicking on the link) taken to a page describing the benefits of enabling JavaScript and some simple instructions on how to do it (tailored to the browser they are using, off course).

Unfortunately our project is not yet finished so I can’t show you a live example, but I’ve made this demo page where you can see this. Just view the source to see the code.

ps: you’ll see my first jQuery plugin on this demo page, so any comments regarding that are highly welcomed. Off course, you can use the code if you happen to find it useful.

@ operator is slow

21 June, 2009 (09:44)

The @ “operator” in PHP is used to silence any warnings or errors that would otherwise be shown (in the browser or the log). It’s really useful, because sometimes you know you can safely ignore a warning or error, when checking if a GET variable is set for instance. Until today I though that, if used properly and with caution, the @ operator can be freely used. Then I read this article. I really had no idea that PHP is doing so much work behind the scenes to make @ work.
When PHP comes to a statement, that contains the @ operator, it changes error reporting to none and then back, which translates to a trip to the php.ini file.
So after I stopped scratching my head and thinking “why the bloody hell would one do that like so?”, I opened my PHP editor and wrote this simple test to see just how much of a difference this makes. It’s the most common scenario where you check if a GET variable has any content.
First the version with @:

for ( $i = 0; $i < 1000000; $i++ ) {
	if ( @$_GET['var'] != '' )
		echo 'foo';
}

And the version without @:

for ( $i = 0; $i < 1000000; $i++ ) {
	if ( IsSet ( $_GET['var'] ) && $_GET['var'] != '' )
		echo 'foo';
}

I timed the execution of both snippets and here are the results:

  @ version IsSet version
1 1.52496409416 0.196986913681
2 1.48627185822 0.204479932785
3 1.52267694473 0.206820964813
4 1.51263594627 0.207319021225
5 1.49150109291 0.199639081955
6 1.48829102516 0.174983978271
7 1.54369091988 0.206038951874
8 1.52254199982 0.204971075058
9 1.50641703606 0.190815925598
10 1.51343107224 0.203064918518
sum: 15.11242198945 1.995120763778
avg: 1.511242198945 0.1995120763778

The IsSet version is about 7.5 times faster, really amazing. I don't use @ as often as I used to, but I will now try to reduce it to zero. You should do the same.

Aliiike recommendation engine

16 June, 2009 (19:21)

We updated igre123.com today and one of the main new features is the recommended games you see on the right of the game you are playing:

recommended games

You may not see this if you go see for yourself. Either you are viewing a game that hasn’t got enough data collected to show the recommendations or you are one of the “lucky” 20% of users who don’t see the recommendations (we are comparing how well this new feature influences bounce rate, time on page, …).

We are using the Aliiike recommender system which is a breeze to use and gives fantastic results. We simply couldn’t offer better recommendations based on search because games rarely have title or description that would overlap (we have yet to test this on mojvideo.com where this isn’t such a big problem). And if you look at the above picture, showing a bejeweled like game, you can see that recommended games are really related (most of the games are of the same type or are puzzle games).

When you install Aliiike you are simply putting a simple JavaScript tracking code (kinda like google’s analytics) into your product page (product being anything you want, aliiike doesn’t care what it is tracking) which logs how your users move from one product to another (it does that by logging the URL of the product). And then you wait a week or two for the data to collect (you get better and faster results on high traffic web pages as there is more clicks to analyze).

After Aliiike has enough data you can start showing recommendations. There are various ways how you can do that, but all is explained on this page, so I won’t go into any details.

We grab a fresh file with analyzed data every day and store the recommendations into the database, but you could opt for a simpler approach with AJAX for instance.

Anonymous paradise

11 June, 2009 (15:57)

Google’s gmail is great; I can’t imagine working with email without it. Unfortunately, as with everything, there are some issues with it.

Did you know that the following email addresses all “translate” to the same account: not.a.real.email@gmail.com,notarealemail@gmail.com, not.arealemail@gmail.com, n.o.t.a.r.e.a.l.e.m.a.i.il@gmailcom, … ?

This is great, because who could remember where the dots are when somebody tells you his email? But this also means that a user can register on your site using one email multiple times (how many times depends on the length of his email), because he can just randomly rearrange the dots and voila a valid unused email.

So this is really anonymous paradise as he can register countless times (if you ban him for instance) without going trough the hassle of setting up a new email account. I don’t know if other mainstream email providers also have this “feature”.

So the obvious solution would be to remove all the dots when a user registers/signs in using a gmail email, but that could cause some problems later on. What if Google suddenly drops this “feature”? You would wind up with a whole bunch of problems.

I think that a better solution is to store the dot less email into some table when you ban a user. And then at registration you check the email, the user is wishing to register with, against this table (stripping dots off course). This way annoying anonymous users get to use his email only once.

php konferenca 2009

6 June, 2009 (18:15)

This year’s Slovenian PHP conference just finished. This was the second installment of the only PHP event here in Slovenia. It’s a shame I wasn’t there last year so I can’t compare. Overall I was really impressed with everything, all but two talks ware magnificent. Guys from videolectures.net have recorded the whole thing so you will be able to see the conference if you weren’t able to make it.

PHP konferenca 2009

Below are my opinions on the lectures:

Delavnica: OpenID, OAuth in Najdi.si Prijava (Workshop: OpenID, OAuth and najdi.si login):
This workshop showed me that OpenID isn’t that hard to implement (few API calls and you are done). The user experience bugs me (Facebook Connect wins here) and I don’t se mass adoption anytime soon, especially because, apparently, many OpenID enabled web pages are making a white list of OpenID providers that they accept logins from. Najdi.si made their own OpenID provider but they are not really helping with educating users what OpenID with their own custom name.

Delavnica: Varnost in PHP (Workshop: Security in PHP):
Really great workshop, Gašper Kozak walked us trough all the major security issues we, developers, should take care of. Most of the stuff he sowed was known to me and I’ve got them covered in my code, but there were still some things I just stared with my mouth opened. I will address those issues first thing on Monday. Gašper was also kind enough to point some security flaws in my code (he still has to give me details).

Predavanje: PHP brez brskalnika (Lecture: PHP without the browser):
This lecture was about PHP CLI and it showed me some new tricks to use. It also showed me how to do multi-threading properly (something I’m struggling with for quite some time now). Great lecture!

Delavnica: Izdelava Facebook aplikacij in uporaba Facebook Connecta (Workshop: creating Facebook apps with Facebook Connect):
Here we learned how to build Facebook applications and I learned that this really isn’t all that difficult. You build the application just like you are used to, the difference is only that you ask the Facebook API, instead of db for example, for users data. Great!

Predavanje: 10 koščkov kode, ki so mi olajšali življenje (Lecture: 10 code snippets that made my life easier):
Unfortunately I overslept (this lecture was the first of the second day) so I missed half of this lecture. But judging from what I saw it was pretty much useless. Marko Štamcar was showing us some code that would be acceptable for a rookie programmer or would have it’s place 10 years ago.

Predavanje: Keširanje dinamičnih vsebin (Lecture: caching of dynamic content):
One of my favorite lectures, Miha Hribar of 3fs (who was the main sponsor btw) talked about memcache. It was really interesting as we plan on implementing it in the near future and I learned quite allot about how to do this. Very handy!

Predavanje: PHP+Flash=RIA (Lecture: PHP+FLASH=RIA):
Anže Žnidaršič (organizer of the conference) was this lectures speaker. Although I’m not planning on using this anytime soon the talk was interesting as it showed us that there are alternatives to writing PHP applications the “regular” way. Basically the development is very much like ASP.NET if you use flash.

Predavanje: Real-time web (Comet) (Lecture: real time web with Comet):
We are planning on doing a something that will require us to use Comet so this lecture was really helpful. I learned all the missing pieces so I can now dive in and implement the feature (can’t say what it is just yet). There are allot of problems with using Comet (which is just a bunch of technologies wrapped in a common name, just like AJAX) on the client side, but fortunately there are libraries that deal with those problems. The best part is that it works in all mainstream browsers including IE6!

Predavanje: Spletne aplikacije na namizju (Lecture: web applications on the desktop):
Anže already scratched the surface in his lecture but Swizec gave us a in-depth look at Adobe AIR and how to use it. It looks like a nice platform. I only wish he would compare it to Silverlight to give more perspective on the technology.

Predavanje: CodeIgniter PHP Framework (Lecture: CodeIgniter PHP framework):
I hate to say this, but this was the worst lecture of the conference. Tomaž Muraus talked about CodeIgniter but instead of showing us how to do a real web page in it, he basically walked us trough the manual which I can do by myself.

Like I said I’m very pleased with the conference and I’m looking forward to the next one. Maybe I’ll even man up and prepare a lecture/workshop of my own.
I’ve also meat a lot of my fellow php-si.com users and it’s always nice to put a face to a nickname. Really great getting to know you all!