Optimizing High Traffic Massive Data Websites

The big dilemma in web development is that, on the one hand, web pages are expected to do more and more, while on the other hand, are expected to load instantaneously.  A web page that takes longer than 2 seconds to load is considered slow.  By 10 seconds many users give up, and 20 seconds load time is considered completely unusable.  On the other hand, with dynamic data, hundreds of data queries need to be performed to display a single web page.  When thousands of users are simultaneously accessing the page, the server access can get clogged up, increasing the server response time to render the page.

Client Side Optimization

What makes a page take time to be displayed? Loading time of additional files and script execution time.  To decrease initial script execution time, the display initial should be as independent as possible from script execution, and scripts should be reserved for event handling.  To decrease loading time of additional files, there are a few helpful methods.  First of all, each http request has its own overhead, so combine JavaScript and CSS files to make less http requests.  Image files may also be combined into one larger sprite file.  Then, use background position to determine which image to be displayed.  Additionally, since these files are generally static, they may be loaded faster by storing them on a CDN, so that the end user will download them from a distributed server, decreasing network time.

Database Optimization

On the server side, the biggest bottleneck is database access.  To optimize database response time, there are 2 types of optimizations – query optimization and server distribution.  To optimize the queries, the first thing is to make sure that all the necessary indexes are in place.  Every field that is used in a “WHERE”,  “JOIN”, or “ORDER BY” should be indexed.  This should eliminate the most sever inefficiencies.  After that, overhead may be further reduced by monitoring the server for queries that take more resources and use EXPLAIN to find the inefficiencies.  Server distribution is increasing the number of database servers, so that each server will not have a long queue of requests.  To do this, there should be a master server where are write command, such as “INSERT”, “UPDATE”, etc. are executed.  All changes should be replicated on the slave servers.  All read commands, such as “SELECT” should be performed on the slave servers.  To speed things up further when there is greater traffic, additional slave servers should be created, and the requests should be distributed across the slave servers.  The disadvantage of this is that the information queried could be a split-second out of date due to replication time.  It also creates another place where data retrieval can go wrong, when the replication fails.  Still, with large data and traffic, server distribution is absolutely needed for the web site to run at reasonable speed.

Caching

After all the queries are optimized, the website may take time because there are still a large number of queries being executed.  If the data is not constantly changing, there is no need for all the queries to be executed each time a page is loaded.  Instead, the content should be store in memcache.  Content will then load almost instantaneously.    Sometimes, the specific page content is dynamic, but much of the data is static.  Here, the page may still load quicker when the model caches the static data.  Just make sure to invalidate the memchaced content when the data is updated.

External Indexing

Still, if I want to search the website’s data, I need dynamic results that cannot always be cached.  How do I avoid increased database usage? Use and external data index, such as Sphinx to search the data.  You can have it return the ids of each record of the search results.  Once you have the ids, you just look up the records in memcache, and no direct database access is now required to display the search results.

Posted in Uncategorized | Tagged , , , | Leave a comment

Oy Vey Debugging – Fixing PHP Web applications without a debugger

While it is much easier and more efficient to use a debugger such as x-debug to debug your PHP web application, there may be some difficulties on the server stopping one from implementing x-debug.  In this case, we are forced to use the classic debug methods instead.  This article will elaborate on the implementing classic methods in web programming.

Displaying Debug Messages

The simplest way to debug is to display debug messages.  The standard PHP function to do this is “var_dump()“.  var_dump() can be used to display data, including arrays and objects.  With large objects or arrays, the data may be truncated, so you may need to specify the element in the array or object or specifically cast it to a string if it is a virtual string.  You can also use var_dump() or echo to confirm that a certain line was indeed executed.

One disadvantage is that having these extra displays, if left in the production code, there could be unprofessional looking displays on the website.  To avoid this, one should always check the diff before checking in the code.  But then again, if the problem occurs on production, you will never be able to use this method to debug, as it will disrupt the website.  To avoid this potential pitfall, there are alternatives.

One alternative debugging method is writing it to a log.  This will enable to website to display correctly, while the error may be checked only by those with access to the log.  In addition, one can set up their system to write to the log in different events in order to diagnose potential issues and monitor system behavior.  Another possibility is to use a tool such as firePHP (a Firefox plugin), in order to have messages only displayed in the firePHP.  This may allows the developer to check without having to access a log.  Still, since anyone can install firePHP and view your confidential debugging messages, it is best to have it turned off in production.

“Oy Vey” Debugging – Forcing a Crash

One problem with the previous approach is that the method is prone to failure.  The log could fail to be written for a  number of reasons.

var_dump() and echo could be disabled if the system buffers and flushes the output.  Using third-party plugins is also not 100% reliable.  Browsers and plugins are always being updated, and new versions can have compatibility issues.

Another issue is that, while displaying or logging a message will indicate that a line of code was executed, it will might not tell you how you got there.  You can still use debug_backtrace(), but there is another way.

trigger_error('oy vey');

throw new Exception('oy vey');

The error screen now displays all the info you need.

Still, some systems will trap your errors, so in order to force a fatal error by calling a non-existent function.

oyvey();

Or you can also try

die('oy vey');

Just make sure to remove all the debugging stuff before checking in your changes.  The grand World Wide Web audience wants to see a working website and not “oy vey”.

The Blank Screen

Sometimes, none of this helps.  Something is causing the program to crash, and your page turns up blank.  How do you find the guilty line of code?  Sometimes, with thorough knowledge of you project, you can guess what the problem is.  But what when you have no idea why your page is blank?  One possibility is to go to the top starting code in your system is see what executes.  From there, you can work your way top-down into sub-functions.  Another classic debugging method is to comment out everything and uncomment until you find the guilty line.

Using these different methods, you can generally solve your website’s issues without a debugger.

Posted in Uncategorized | Tagged , , , , | Leave a comment

Using Google to look up Web Development Solutions

Rav Nachman said, “Saying I don’t know is negligent.” (Talmud Baba Metzia 35a)

In the age of Google, Rav Nachman’s statement can be extended way beyond its original meaning.  What do you mean, “I don’t know”?  You will be told to just Google it and sent a link that looks like http://www.lmgtfy.com/?q=some+question.

But can you answer all your programming questions by turning to Google?  Will Google always answer “how do I do that”?  Some problems may be too specific to answer with Google.  There are still other issues that you may have to dig a little deeper to find the answer.

Asking the Right Questions

If you don’t get a good answer, you’re probably not asking the right question. One common problem  is getting the terms wrong.  For example, say that you do not know the term “checkbox”.  Instead you search for “switchbox” instead.  You will then get results that talk about boxes with switches instead of the type of form input you are looking for.  To look for the right term, you search for “form input types”.  You should now find out that the correct term is “checkbox”, and you can proceed to search for the specific information you were looking  for about checkboxes. While there is no substitute for professional knowledge, sometimes with some guessing and a few tries searching, you may eventually get to the correct term.

Another important tip is to include the name of the programming language or library in the search.  If you are using an outdated or not very commonly used framework, you are much more likely to be out of luck.  Usually, if your question is something that many other people have dealt with, you will find your answer once you’ve asked the right question.  Then again, if you don’t find the answer in your search, you may need to recheck your code.  It might just be your own mistake and not a common issue.

Useful Sites

https://www.google.com/ Needs no introduction.  Usually I can find my answer by Google-ing the question.

http://www.wikipedia.org/ Contains basic info on whatever I am totally unfamiliar with.

http://www.php.net/ or other language/platform specific sites.  It’s the official source defining the behavior of PHP, and the comments usually answer the questions the articles do not.

http://www.w3schools.com/ contains tutorials on most common open source languages.

http://stackoverflow.com/ Most of your questions have been already asked there, and if not, this is the best place to ask.

Methods that don’t seem to work

One thing that never works for me is asking my question on Facebook.  My high school buddies are just not the forum for such technical questions.  Even asking on LinkedIn doesn’t seem to cut it.  I usually need expertise beyond my narrow circles.  Same by spamming all my email contacts – just don’t bother.   You need the world’s experience and expertise, and that’s why you’re checking on the Internet.

 

Posted in Uncategorized | Tagged , , | Leave a comment

PHP/AJAX Shipping Calculator for UPS: getting a list of the available shipping services between locations

PHP/AJAX Shipping Calculator for UPS: getting a list of the available shipping services between locations

There are already guides available for building a general UPS shipping calculator form, and with a little knowledge of PHP, one can modify the sample to have the shipping calculated on one’s own shopping cart.  The problem with such a static form is that it lists all shipping services that UPS provides anywhere. 

<select name="selService">
   <option value="1DM">Next Day Air Early AM</option>
   <option value="1DA">Next Day Air</option>
   <option value="1DP">Next Day Air Saver</option>
   <option value="2DM">2nd Day Air AM</option>
   <option value="2DA">2nd Day Air</option>
   <option value="3DS">3 Day Select</option>
   <option value="GND">Ground</option>
   <option value="STD">Canada Standard</option>
   <option value="XPR">Worldwide Express</option>
   <option value="XDM">Worldwide Express Plus</option>
   <option value="XPD">Worldwide Expedited</option>
   <option value="WXS">Worldwide Saver</option>
</select>

 

This, however, makes it difficult for the user.  If I am mailing a package within the United States, and I select “Worldwide Saver”, UPS will respond with an error message that this service is not available between the specified locations.  To make the form more usable, the select should only list the services that are actually available.  The question for the developer is — how do I know which of the services are actually available, given the origin and destination locations?

 

This article discusses how to request the list of available rates from UPS and how to read the response.  Once this is accomplished, someone with who knows PHP and AJAX can easily put the code in the form to have the select list generated automatically.

Sending Request to UPS

Just as in the basic shipping calculator, the URL to request information from UPS is http://www.ups.com/using/services/rave/qcostcgi.cgi.  Here, however, since the request is to get a list of available rates, the parameter “10_action” should be set to “4”.

The other required parameters are:

accept_UPS_license_agreement – must be set to “yes”

14_origCountry – the country the package is being sent from

15_origPostal – the zip code (postal code) the package is being sent from

origCity – the city the package is being sent from

23_weight – required, but for our purposes, you can use any number.

47_rateChart – required, can be any of the following: Regular+Daily+Pickup, OP_WEB, OP_PHONE, One+Time+Pickup, Letter+Center, or Customer+Counter.  Not important which one.

48_container – Since this is also required but not significant for this query, I use the value “00”.

49_residential – 01 (residential) or 02 (commercial) required but not significant

13_product required but can be anything of 3 letters.  I use “qqq”.  The purpose of our request is to get the available values when you pass this to the price request, so by definition you never know what it should be.

19_destPostal – the zip code (postal code) the package is being sent to

20_destCity – the city the package is being sent to

22_destCountry – the country the package is being sent to

 

Hence, we can build a function to request the list of available rates as follows:

 

<?php

function request_ups_available_services($orig_city, $orig_postal, $orig_country, $dest_city, $dest_postal, $dest_country)

{

 $ups_request=’http://ww.ups.com/using/services/rave/qcostcgi.cgi ‘

  .’?accept_UPS_license_agreement=yes’

  .’&10_action=4′

  .’&23_weight=1′

  .’&48_container=00′

  .’&49_residential=01′

  .’&13_product=qqq’

  .’&47_rateChart=Regular+Daily+Pickup’

  .’&origCity=’.$orig_city

  .’&14_origCountry=’.$orig_country

  .’&15_origPostal=’.$orig_postal

  .’&19_destPostal=’.$dest_postal.

  .’&20_destCity=’.$dest_city

  .’&22_destCountry=’.$dest_country;

 return file_get_contents($ups_request);

}

?>

 

Reading UPS response

The response string should look something like this:

UPSOnLine4%1DA%50665%US%88000%US%106%1%43.39%0.00%43.39%End of Day%

4%2DA%50665%US%88000%US%206%1%18.99%0.00%18.99%End of Day%

4%3DS%50665%US%88000%US%306%1%13.59%0.00%13.59%End of Day%

4%GND%50665%US%88000%US%006%1%8.21%0.00%8.21%End of Day%

 

How do we read the string and translate it into a list of services?  There may be an official method, but this works for me.  All services are 3 characters, and from the general form, we have a list of all available services:

<select name="selService">
   <option value="1DM">Next Day Air Early AM</option>
   <option value="1DA">Next Day Air</option>
   <option value="1DP">Next Day Air Saver</option>
   <option value="2DM">2nd Day Air AM</option>
   <option value="2DA">2nd Day Air</option>
   <option value="3DS">3 Day Select</option>
   <option value="GND">Ground</option>
   <option value="STD">Canada Standard</option>
   <option value="XPR">Worldwide Express</option>
   <option value="XDM">Worldwide Express Plus</option>
   <option value="XPD">Worldwide Expedited</option>
   <option value="WXS">Worldwide Saver</option>
</select>

 

Hence, we split the response by the separator character (“%”) and check each entry if it is a service type.

Here is a function that takes the response from UPS and generates a list of available services.

<?php

function generate_service_list_from_ups_response($ups_response)

{

$master_ups_service_list=array(

’1DM’=>’Next Day Air Early AM’,

’1DA’=>’Next Day Air’,

’1DP’=>’Next Day Air Saver’,

’2DM’=>’2nd Day Air AM’,

’2DA’=>’2nd Day Air’,

’3DS’=>’3 Day Select’,

‘GND’=>’Ground’,

‘STD’=>’Canada Standard’,

‘XPR’=>’Worldwide Express’,

‘XDM’=>’Worldwide Express Plus’,

‘XPD’=>’Worldwide Expedited’,

‘WXS’=>’Worldwide Saver’

);

$ups_service_list=array();

$ups_server_list=split(‘%’, $ups_response);

foreach($ups_server_list as $this_service)

{

if(isset($master_ups_service_list[$this_service]))

$ups_service_list[$this_service]=$master_ups_service_list[$this_service];

}

return $ups_service_list;

}

?>                                                              

Posted in Uncategorized | Tagged , , , , , , , | 1 Comment

Developing multilingual websites using PHP, part 3 – Right-to-Left vs. Left-to-Right

The problem

 

 

When developing a website for Hebrew and other languages, there is an additional issue to deal with.  If all the languages are left-to-right, then it is straightforward to use the same template or design with all languages.  All that needs to be switched when the site is viewed in a different language is the text.  However, with Hebrew, people are reading the website in the opposite direction.  Many website designs have something displayed on the right or left side of the page.  When the page is read in the opposite direction, it is usually advised to put the displays on the opposite sides of the page.  To do this, one may just change the entire direction of the page from left-to-right to right-to-left by inserting this piece of CSS in the “body” tag:

style=”direction:rtl”

 

 

Alternatively, one may put in the CSS file:

body { direction:rtl }

 

 

Still, even after changing the direction of the entire document, there remains an issue – the border definitions in CSS are also in the opposite direction.

For example, if I want to have a blue, solid border separating the left area and the main area, I can assign a class “left_area” to the left area and define the following in CSS:

left_area { border-right: solid blue 1px }

However, if I change the direction of the document to right-to-left, and the “left_area” is now on the right side of the page, instead of having a border in between the “left_area” and the main page, the CSS definition above will cause the line to be displayed on the right side of the page, and not in between the sections.

Solutions

 

 

One possible solution is to make a separate template or CSS file for right-to-left languages.  The disadvantage is that this causes duplicate code, and if the design is changed, it needs to be changed in twice as many places.

My suggestion is to dynamically generate the CSS file using PHP.  Instead of calling the CSS file style.css, I would call it style.css.php.  In the link, one can add a parameter dir to indicate the direction of the document.

Hence, instead of this link in the HTML header:

 

 

 

One can use the following link instead, where the PHP variable $page_dir indicates the direction of the document.

 

 

In the CSS document itself, one would then assign variables the appropriate values for the directions.

 

 $page_dir=isset($_REQUEST[‘dir’])? $_REQUEST[‘dir’]:’ltr’;

 

 

 $left=($page_dir==’ltr’)?’left’:’right’;

 

 

 $right=($page_dir==’ltr’)?’right’:’left’;

 

 

?>

 

 

In the CSS document itself, instead of hard-coded right and left directions, like this:

left_area { border-right: solid blue 1px; }

 

 

One can use the variables to define the directions, like this

left_area { border-: solid blue 1px; }

 

 

Doing this, one can design the website for one language and seamlessly have it displayed in a different language in the opposite direction.

Posted in Uncategorized | Tagged , , , , , , , , | Leave a comment

Developing multilingual websites using PHP, part 2 – database connection character sets for MySQL

The problem

 

 

Ok.  I did everything it said in the previous article, and both my database and my site are working in UTF-8.  Still, anything in Hebrew I enter into PHPMyAdmin comes up as question marks on my site.  If I enter in data from the website, it comes up as gibberish on PHPMyAdmin.  When I change character coding in my browser from UTF-8 to Hebrew-ISO (ISO 8859-8) or Hebrew-Windows (Windows 1255), the data is displayed correctly.  Which is incorrectly handling UTF-8, my website, or PHPMyAdmin?

The solution – set the correct database connection character set

 

 

The database connection character  set, or “client encoding”, is the character set that the client uses, which does not have to be the same as the server encoding.  For example, one can have a website that is rendered in Hebrew-ISO characters, while the database uses UTF-8.  If the client encoding is set to “hebrew”, the SQL queries will use Hebrew-ISO characters, which will be translated into UTF-8 characters on the server.

The function to check the client encoding is mysql_client_encoding(), and the function to change the client encoding is mysql_set_charset().  Regardless of how the database is configured, the default client encoding is “latin1”.  The possible values are listed at the end of the article.

Hence, if you want the site to be displayed with the Hebrew-ISO character set, after you connect to the database, you should call the following command in PHP:

mysql_set_charset(‘hebrew’);

 

 

If the site is displayed using the UTF-8 character set, then you can use the following command instead:

mysql_set_charset(‘utf8′);

 

 

Valid values for the database connection character set

 

 

 (from http://bugs.php.net/bug.php?id=45921, can be derived by the SQL statement “show character set”)

+———-+—————————–+———————+——–

 

 

+

 

 

| Charset  | Description                 | Default collation   | Maxlen

 

 

|

 

 

+———-+—————————–+———————+——–

 

 

+

 

 

| big5     | Big5 Traditional Chinese    | big5_chinese_ci     |      2

 

 

|

 

 

| dec8     | DEC West European           | dec8_swedish_ci     |      1

 

 

|

 

 

| cp850    | DOS West European           | cp850_general_ci    |      1

 

 

|

 

 

| hp8      | HP West European            | hp8_english_ci      |      1

 

 

|

 

 

| koi8r    | KOI8-R Relcom Russian       | koi8r_general_ci    |      1

 

 

|

 

 

| latin1   | cp1252 West European        | latin1_swedish_ci   |      1

 

 

|

 

 

| latin2   | ISO 8859-2 Central European | latin2_general_ci   |      1

 

 

|

 

 

| swe7     | 7bit Swedish                | swe7_swedish_ci     |      1

 

 

|

 

 

| ascii    | US ASCII                    | ascii_general_ci    |      1

 

 

|

 

 

| ujis     | EUC-JP Japanese             | ujis_japanese_ci    |      3

 

 

|

 

 

| sjis     | Shift-JIS Japanese          | sjis_japanese_ci    |      2

 

 

|

 

 

| hebrew   | ISO 8859-8 Hebrew           | hebrew_general_ci   |      1

 

 

|

 

 

| tis620   | TIS620 Thai                 | tis620_thai_ci      |      1

 

 

|

 

 

| euckr    | EUC-KR Korean               | euckr_korean_ci     |      2

 

 

|

 

 

| koi8u    | KOI8-U Ukrainian            | koi8u_general_ci    |      1

 

 

|

 

 

| gb2312   | GB2312 Simplified Chinese   | gb2312_chinese_ci   |      2

 

 

|

 

 

| greek    | ISO 8859-7 Greek            | greek_general_ci    |      1

 

 

|

 

 

| cp1250   | Windows Central European    | cp1250_general_ci   |      1

 

 

|

 

 

| gbk      | GBK Simplified Chinese      | gbk_chinese_ci      |      2

 

 

|

 

 

| latin5   | ISO 8859-9 Turkish          | latin5_turkish_ci   |      1

 

 

|

 

 

| armscii8 | ARMSCII-8 Armenian          | armscii8_general_ci |      1

 

 

|

 

 

| utf8     | UTF-8 Unicode               | utf8_general_ci     |      3

 

 

|

 

 

| ucs2     | UCS-2 Unicode               | ucs2_general_ci     |      2

 

 

|

 

 

| cp866    | DOS Russian                 | cp866_general_ci    |      1

 

 

|

 

 

| keybcs2  | DOS Kamenicky Czech-Slovak  | keybcs2_general_ci  |      1

 

 

|

 

 

| macce    | Mac Central European        | macce_general_ci    |      1

 

 

|

 

 

| macroman | Mac West European           | macroman_general_ci |      1

 

 

|

 

 

| cp852    | DOS Central European        | cp852_general_ci    |      1

 

 

|

 

 

| latin7   | ISO 8859-13 Baltic          | latin7_general_ci   |      1

 

 

|

 

 

| cp1251   | Windows Cyrillic            | cp1251_general_ci   |      1

 

 

|

 

 

| cp1256   | Windows Arabic              | cp1256_general_ci   |      1

 

 

|

 

 

| cp1257   | Windows Baltic              | cp1257_general_ci   |      1

 

 

|

 

 

| binary   | Binary pseudo charset       | binary              |      1

 

 

|

 

 

| geostd8  | GEOSTD8 Georgian            | geostd8_general_ci  |      1

 

 

|

 

 

| cp932    | SJIS for Windows Japanese   | cp932_japanese_ci   |      2

 

 

|

 

 

| eucjpms  | UJIS for Windows Japanese   | eucjpms_japanese_ci |      3

 

 

|

 

 

+———-+—————————–+———————+——–

 

 

Posted in Uncategorized | Tagged , , , , , , , , , , , , , , , , , , , , , , , , , | Leave a comment

Developing multilingual websites using PHP, part 1

In today’s World Wide Web, people expect to read websites in their own language.  Many Israeli websites now appear in Hebrew for Israelis, in English for the international community, and in other languages, such as Russian or Arabic.  To make a website work properly in many languages, one must take care of a few issues.  This article will deal with the general issues of making a website multilingual, and the next week’s article should discuss the specific issues of left-to-right vs. right-to-left.

Character Sets

 

 

 

 

 

Consistent use of character sets will make sure that the local-language letters are displayed correctly.  Inconsistent use of character sets will cause the browser to display question marks or gibberish instead.

One character set for displaying Hebrew and English characters is ISO 8859-8.  This standard is the same as ASCII for the first 127 characters, and uses some of the remaining 127 characters for Hebrew.  Most older Hebrew/English websites use this standard, and it is still considered an official ISO standard.

Another option is UTF-8 (Unicode). This standard uses one byte for Latin characters and two bytes for international characters, such as Hebrew or Russian.  This is the recommended character set because it allows one to have a single database that stores data for most common languages.  To define a file as a UTF-8 file, one must define the character set in the editor.  When a file is saved as UTF-8, it will contain the Byte Order Mark (BOM), so that editors will identify it as a UTF-8 file.

For the browser to identify the character set, it should be defined in the header.  In PHP, it can be defined by adding the following line at the beginning of the page:

 

 

 

 

 

Alternatively, one may use the following line within the html section:

 

 

 

 

 

Pages loaded by AJAX must also have a character set header to make sure the section dynamically produced is rendered correctly.

Additionally, it is important to make sure the database and administration software are also set up for the correct character set, and any third party code generator  needs to be configured for the character set as well.

 

 

 

 

 

Dictionary for texts

 

 

 

 

 

When the same site is rendered in several languages, it is important that every text display appears in the selected language.  This includes regular texts, buttons, popup messages, emails, and everything else.  This requires that every text display retrieve the text from a data dictionary.  There are a few possible ways of storing a text dictionary.

·         In the database

 

 

 

 

 

The advantage is that the data dictionary is completely separated from the code, so it is easier to have non-programmers manage the text dictionary.  The disadvantage is that database data is not generally treated as static, and a database administrator could accidently erase the dictionary when erasing the test data.

·         A formatted text file

 

 

 

 

 

This takes some extra work in setting up a format and developing functionality to read the file.

·         A PHP file containing define statements

 

 

 

 

 

If one is doing it this way, it is advisable to have a naming convention to make it clear what is a language-dependent constant.  Some frameworks, such as Smarty, use this method.

·         A PHP file containing an array of definitions

 

 

 

 

 

The file would look something like this:

 

$dictionary_array=array

 

 

 

 

 

(

 

 

 

 

 

 ‘definition1’=>’text1’,

 

 

 

 

 

 ‘definition2’=>’text2’,

 

 

 

 

 

 

 

 

 

 

);

 

 

 

 

 

?>

 

 

 

 

 

Every text display would then need to check for the value in the array.

Database data in multiple languages

 

 

 

 

 

There are two possibilities in making the data in the database work with multiple languages.

·         Extra fields in tables with multilingual data

 

 

 

 

 

For example, if there is a field “city” which needs to be rendered in both Hebrew and English, the table would have a field “city_he” and another field “city_en”.  This solution works well if the site has only two or three languages and there is no need to add more languages.  It is much easier managing all the data within one table with a fixed number of fields.  However, if one wants to add morel languages, it would require modification of the database, and this means the site can never be left permanently to non-DBA’s to manage.

·         An additional table for each table that has multilingual data

 

 

 

 

 

For example, if the table “cities” has the field “latitude” which is not language dependent and the field “name” which is different for each language, there would be 2 tables – “cities” and “cities_lang”.  “cities” would contain the fields “id” and “latitude”, and “cities_lang” would contain the fields “id”, “city_id”, “lang”, and “name”.  If the site is displayed in 5 languages, for each record in “cities”, there would be 5 records in “cities_lang”.

This makes queries more complicated, as an additional join is required, and it also makes more work each time one adds a record to “cities”.  The advantage is that, when one adds more languages, there is no need to change the database structure or queries.

Defining current language

 

 

 

 

 

Another issue in multilingual websites is defining the current language.  Here are some possibilities to determine in what language to display the content.

·         Selected language

 

 

 

 

 

If the user selects a language to view the website, that’s what language it should be viewed in.  To keep this language when traversing pages in the website, the programmer should store the current language either in the “session” or in a cookie.

·         The language of the browser. 

 

 

 

 

 

Usually, the settings of the browser contain one or more preferred languages.  Below is some PHP code to detect if one of the browser’s languages is a language that the website may be displayed in.  This code uses the international 2-letter code standard.

(Adapted from sample code in php.net)

 

if(isset($_SERVER['HTTP_ACCEPT_LANGUAGE']))

 

 

 

 

 

 {

 

 

 

 

 

  $lang_list=$_SERVER['HTTP_ACCEPT_LANGUAGE'];

 

 

 

 

 

  $lang_list=split(‘;’, $lang_list);

 

 

 

 

 

  $lang_list=$lang_list[0];

 

 

 

 

 

  $lang_list=split(‘,’,$lang_list);

 

 

 

 

 

  foreach($lang_list as $lang)

 

 

 

 

 

  {

 

 

 

 

 

   $lang_parts=split(‘-’,$lang); // treat en-us as “en”

 

 

 

 

 

   if (language_exists($lang_parts[0]))

 

 

 

 

 

   {

 

 

 

 

 

    $selected_language=$lang_parts[0];

 

 

 

 

 

    break;

 

 

 

 

 

   }

 

 

 

 

 

  }

 

 

 

 

 

 }

 

 

 

 

 

?>

 

 

 

 

 

·         Default language

 

 

 

 

 

When all else fails, there needs to be a default language to display the content in.  If there is a large international audience, it will usually be English.  If the site is intended for use within Israel only, it will usually be Hebrew.

Conclusion

 

 

 

 

 

We see here that, while it is much more work having one dynamic website displayed in many languages, if one follows these steps, one can have a website rendered in an unlimited number of languages. 

Posted in Uncategorized | Tagged , , , , , , , , , , , , , , , , , , | Leave a comment

Using free scripts to develop websites

Using free scripts to develop websites

It’s all about “keeping up with the Jones’s” on the Internet.  If Jones’s website has draggable, flashing, flying boxes, Smith feels his site also has to have them.  For me, as a developer, this is good because it keeps up the demand for website development and redevelopment. This helps to keep me employed. However, it also poses a challenge – how do I put all the features seen on the Internet into the website I am developing?  If I am an intermediate developer, where do I get the technical knowledge to develop all the new widgets myself?  And even if I am such an advanced developer that I can do everything, is it the most efficient use of my time to re-invent every new feature that a web developer on some other site created?

Fortunately for web developers, there are several scripts available on-line.  Some of them are free, and some have licensing fees.  Some scripts with licensing fees also have free versions to try, so that one may verify that they work before paying for them.

 

Is it really free?

In the Open Source community, there are several different types of licenses.  Most of them are intended to allow further development, so they generally come with the ability to modify the code.  Usually, one who uses such scripts is required to keep the credit comments in the code.  If it is a client-side script, this means that savvy developers viewing your website will be able to find out from where you got your code.  Some free scripts also require or request a link back to the script provider.  It is important to note that not all Open Source scripts are free of charge, but they generally come with conditions that allow the developer to have the source code and fix it.

In short, there are often conditions, but it should not be a problem for the web developer to comply with them, making these scripts essentially free.

 

Why should people develop free scripts?

In the Open Source community, many developers originally create something that they want or need for their own software or website.  As good citizens of the Open Source community, they reciprocate for the software and scripts that they have received by making their own scripts available. 

Another motivation for someone to develop a free script is the “giving away for free” business model.  One possible gain is obtained by selling premium services for a fee.  Another is by offering customization for a fee.  Still another is that, by publishing a free script, the developer proves his/her expertise and generates professional recognition.  This can improve the chances of securing future projects and development jobs.

 

Advantages of free scripts

·         Enable using expert knowledge for maintaining advanced features

As we said, the boss will want his/her website to have all the features of the other guy’s website, and it is not practical to develop all the advanced features from scratch.

·         Save time over writing the script from scratch

Why spend more time when you can do the job in less time?

·         They’re free

Even the scripts which have a licensing fee are usually much cheaper than the cost of the extra development time.

·         Come with source code, so they can be modified

Open Source scripts, as opposed to commercially sold packages and libraries, come with the sources fully readable and modifiable.  If there’s a bug, the developer on site can fix it.  If customization is needed, it can be done.

Disadvantages

·         No guarantee

The licenses on free scripts generally say that the scripts comes “as is” with no guarantees. If the scripts do not work or do not behave as expected, you’re out of luck.  To use them, you need to either be able to fix the problems yourself, or to have someone on hand who is competent enough.

·         No customer support

No one is being paid to give technical support for these scripts.  However, many of these scripts have sites with forums where users can assist each other to find solutions for problematic issues.

·         Open Source license requirements when reselling

As we said, many of the scripts come with licensing requirements, such as making the source code available when redistributing it.  This can be an issue when one wants to make packaged, closed-source software.

·         Must debug others’ code

It’s always easier to debug one’s own code than somebody else’s.  Some useful scripts may have thousands of lines of code and be built with complicated structures.  These scripts are developed for free, and no one paid the author to make them easy to read and maintain.  If there’s a bug, it’s up to you to fix it.  If you need customization, you must delve into the code and fix it yourself.  This is not for the faint-hearted programmer.

 

Foundation scripts

There are some foundation scripts which create the basic graphic effects, but another layer is needed for practical use.  One such library is http://script.aculo.us.  It has all sorts of JavaScript-based graphic and drag-and-drop effects.  On a site I recently developed, I downloaded one wrapper library for iGoogle-style boxes and another library for CSS Popups, both requiring script.aculo.us as a foundation.  There are several other foundation libraries out there, such as Yahoo’s API and others.

 

How to find free scripts

·         Knowing from experience

Let’s face it.  Even with the Internet, there’s no substitute for knowing where to find things.  From my experience, search engines usually do not point me to the best scripts.  Often, those who are savvy in their script writing are not as expert in placing them highly ranked on search engines.  The best way to find good scripts is either from one’s own experience or knowing someone who knows.

·         Forums

The next best way is peer-to-peer forums.  Some are even dedicated to finding scripts.

·         Search engines

Nevertheless, one can still find many good scripts by searching on Google or another search engine – at your own risk.  Especially if one is not familiar with a particular script, it is up to the user-developer to test it and make sure it works.  Once I had to download about 20 scripts I found in search engines until I finally found one which I got to work like I wanted.

 

Conclusion

Here we have seen another aspect of 21st century programming – taking available scripts and making them work on one’s own website.  Today’s demands no longer make writing all graphic aspect of programming  feasible or worthwhile to completely program from scratch.  There are then two options – buying pre-written, closed-source enhancement or taking downloading free, Open Source scripts.  It may be a matter of personal preference, but when I park my car, I usually look for free parking.

 

The next article should be on tips and tricks in making one’s website multilingual.

Posted in Uncategorized | Tagged , , , , , , , , , | 1 Comment

How does your website look on the other guy’s computer?

One major challenge for web developers is to have the site look just right on the various web browsers.  While there are official standards how all the browsers are supposed to interpret HTML and CSS, in practice, each browser has its quirks, and while the page may look one way on my computer, if one is unscrupulous in web development, the page may look unexpectedly different when someone else views it.

Download major browsers

The first thing you need to do is to download all the major browsers.  While most of the world will view your website through either Internet Explorer or Firefox, it’s advisable to also cover less common browsers, such as Opera, Safari, and Konqueror.  These can be downloaded on their respective websites.  It is also recommended to have both the most recent and previous versions of these browsers. For more complete testing, it is also advisable to have different types of operating systems and computers, such as Windows, Macintosh, and Linux, available. Another test is to install different graphic resolutions on the computers to see how the page looks when the screen is larger is smaller.

Once this is done, you need to test each web page on all the possible platforms.  For more thorough testing, it is also advisable to do screenshots of each page view, paste them in a graphics program, and measure the size and spacing of everything.

This may seem quite a bit time consuming, and it really is.  Whoever is paying for the development of the website will have to decide whether it is enough for the website to look just right to 95% of the world or if the extra resources should be used to perfect the site for 99% of the Internet-viewing world.

Reasons why appearance may vary

1.       Bugs in different browsers

Some of the major browsers have bugs, where the HTML or CSS is not rendered correctly.  Unfortunately, those reading the web page usually do not know this, so it’s the developer who looks bad, not the web browser.  It’s the developer’s job to clean up after the web browser’s bugs and find the workarounds to make the site look Ok.

2.       Different strictness in interpreting HTML and CSS

For example, if I write a tag <a href=”http://anywhere.com>, Internet Explorer will cover up my mistake of omitting the closing quotation mark, while Firefox will not forgive, and all the content of the page following this will be considered part of the reference, and much of the remaining content on the page will not visible.  Syntax of such pages needs to be carefully checked, either manually or with an automated syntax checker, many of which are available online.

3.       Different rules for inheritance..

Take the following example:

<div style=”width:10px;padding:10px”>

<div style=”width:10px”>hello</div>

</div>

In Internet Explorer, the inner DIV inherits the padding property from the outer DIV’s padding property, so it will also have a 10 pixel padding, making the overall length 10 pixels larger on each side.  In Firefox, however, only the outer DIV will have the 10 pixel padding.

 

How to fix the appearance

1.       Use debuggers

Each browser should have debugging add-ons, which can be downloaded.  I use DebugBar for Internet Explorer and FireBug for Firefox.  With these debuggers, one can view how the DOM is actually rendered and how the CSS is interpreted.  Once I do this, I usually see where the problem is.

2.       Check the Internet

Fortunately for me, when there is some quirk in a particular browser, there have been thousands of other developers who noticed it before me, some of them who will write about it on the Internet.  To find articles and discussions about such issues, I formulate the key words about my issue and enter it into my favorite search engine.  Additionally, many web browsers have their own forums to discuss issues specific to the browsers.  Most of the time, I will find an article or discussion with a solution to the problem I am having.

Here, we see that, following a series of straight-forward steps, any web developer with basic knowledge of the major tools we use can make the site look just right for most of the Internet audience.

Posted in Uncategorized | Tagged , , , , , , , , | Leave a comment