oateck.com

Discovering the Programming World
Welcome to oateck.com Sign in | Join | Help
in Search

Programming Tips By Omar AlBadri

  • Better Php Caching

    I read many interesting articles on caching that all do the job. The problem I have with most of the techniques is that they do not show you how to implement caching for High Traffic sites. Let look at what caching is first

     

    What is Caching?


    Most web sites generate dynamically created content. To generate this content the web service usually has to query some data source(Database, XML, etc.) and output HTML to your web browser. Problem is that when you have thousands of users hitting your site, these dynamic request can cause serious overhead on your web server as it has to process many request which will cause you site to run slowly. See image:

     

     

     

     

     

     

     

     

    Enter Caching

    How can this problem be avoided? Consider this: Most web pages are updated periodically and perhaps need to be refreshed every half an hour or so. As in the dynamic content of the site really does not need to execute per every web request, but every X amounts of minutes. Lets say you run a News site and you receive a average new article every 10 minutes. So it would make sense to only allow the site to update every 10 minutes. This will really increase your performance and keep the site fresh.

    How Caching Works


    The concept of caching is simple. A user request your web page. The php code checks to see if the page needs to be updated. If yes then run the dynamic queries and refresh the content. If no then return the cached page. (see Image below):

     

    Implementing Simple caching


    Caching is fairly simple to implement lets look at a overview of what we want our script to do

    Sounds easy enough lets look at some code:

    $cfile = "cache/cachedpage.HTML";
    if (file_exists($cfile))
     {
    // the page has been cached from an earlier request
    //include and output the cached page

    include($cfile);

    // exit the script, so that the rest isn't executed

    exit;
    }
    ?>

    <HTML>
    .
    . Your HTML here
    .
    </HTML>

    <?php

    // open the cache file for writing
    $fp = fopen($cfile, 'w');
    // save the contents of output buffer to the file
    fwrite($fp, ob_get_contents());
    // close the file fclose($fp);
    // Send the output to the browser ob_end_flush();
    ?>

    A Fundamental Flaw


    While the above code will work for most of the sites out there, what will happen if we implement this on a high traffic site? Let consider the following scenario: You have a high traffic site that averages two users a second. Your dynamic content take around 3 seconds to regenerate and your cache page just expired.



    We can see that image that you allows 5 more request then needed. On a high traffic site you would site extremely slow downs during this moment. For even higher traffic sites(Digg.com, Fark.com, etc) where they average 10 users per second this could be exponentially a even bigger problem.



     

    Better Php caching

    In order to over come this issue, we are going to lock the file when the first request for a new cache file comes in. Then, if another users makes the request before the first cache file is written,  it will attempt to lock a file that is already locked. If this then we simply return the cache until the first user has unlocked the file

    <?php
          $cfile = "cache/cachedpage.HTML";

       
          $cfile ="cache/".$reqfilename.".html";
     
          $cachetime = 30*60; // 30 minutes
          // Serve from the cache if it is younger than $cachetime
      

    if (file_exists($cfile ) && (time() - $cachetime< filemtime($cfile ))) 
    {
      
         //if cache is not expired return cache files
         include($cfile );
          exit;
      
     }
     else
    {

    //open file and attempt to lock
     $fp = fopen($cfile , 'w');
     if( flock($fp, LOCK_EX))
     {
           ob_start(); // start the output buffer
     }
     else
     {
        //if cant lock then return the previously generated cache
        include($cachefile);
        exit;
     }
    }
      
    ?>

    <HTML>
    .
    . Your HTML here
    .
    </HTML>

    <?php  

         // open the cache file for writing 
          flock($fp, LOCK_UN); // unlock the file
         
           // save the contents of output buffer to the file 
          fwrite($fp, ob_get_contents());
      // close the file
          fclose($fp);
      // Send the output to the browser
           ob_end_flush();
      
      
    ?>

    Going over the code we see that we are now locking the file before we write to it. Any other users whom preform the cache request will attempt to lock a lock file and it will fail and they will return the old cache file. This ensures that only one cache file request is preformed in spite of how many users.

    Special thanks to Alex Gonzales(www.branchint.com) for some help on this. Please leave a comments/questions or improvements.

     

  • Data Integration using a MultiThreading Kernel

    Sometimes you have a problem where two incompatable system, (such as a POS/ Cash Register) , needs to integrate with a new software systems (such as a new website) data. The issue is that the POS system is the Master of Inventroy (MOI) and needs to update the websites database peridocally to sync up the inventories.

    There are three ways to accomplish this:

    1) Create a outbound xml channel to your database that updates the inventory periodacally. Problem: expensize as you would need a Biztalk server or something of the sort and complex as you will have to define and map the outbound and inbound structure
    2) Have the admin mannually update the products in stock.Problem: Inpracticall even if you created a upload page the  user would have to spend hours a day entering and verifing the data.
    3) Create a multithreading kernel that polls a specifc location and imports the data based on a export file.

    Most Inventory control systems have a export functionality, wither it is in XML or some propietary system. You simply need to create a kernal that will poll a particular location and pull in the data as soon as the Inventory control system spits it out.

    Here the outline of what we want to accomplish:
    1. A Multi-Threading
    2.  Some Feebback and Logging
    3. A Folder location where the export file will be continously polled.

    Program
    Start by opening Visual studio and create a Windows application in C#.

    Lets start by adding the basic elements that will contrust our kernel:

    1. Add a Start and Stop button and a browse button
    2. Add a text box of the File Directory to be inserted
    3. Add a Multiline TextBox that will display your messages
    4. Drop a OpenFileDialog Control
    5. Drop a Worker thread

    Your form should look something like this:

    Coding

    Double click the browse button and use the OpenFiledialog control which I named fbd to show and grab a file location. This will be the location were we will poll for a export file.

    Sample Code
    {
    fbd.ShowDialog();
    txtFolderLocation.Text = fbd.SelectedPath;
    }
     Next we will look at the start and stop buttonThinking about what we want to do: First the Start and Stop button we be associated with the ThreadWorker component that previously dropped on the form. Second we want to report all messages to the large Text box.
     

    Lets look a the properties of the Thread are:

    The only property that we are conserned with is the WorkerSupportsCancellation. We want to be able to stop the Thread gracefully, so this property needs to be set to true.Now lets look at the events of the Thread



     

     

     

     

    The only two things we are concerned win are the DoWork and the RunWorkerCompleted Event. The DoWork is is the function that is going to be called when you start the thread and RunWorkedCompleted is the event called when you push the stop button. Double click on these event to create the Events.DoWork The function of this event is to poll the folder selected previously the code is simple:

    Code:

    private void thread1_DoWork(object sender, DoWorkEventArgs e)
    {
    while
    (!thread1.CancellationPending)
    {
    if (File
    .Exists(path))
    {
    //do something with the file
    }
    }

    The only think to notice is that we are looping on the thread1.CancellationPending not being set to true. This allows us to Stop the thread by pressing the stop button.
    When the Stop button is pressed the
    private void thread1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {}
    is called. Use this function to do any clean up code and ideally write the log file.Next we will code the Start and Stop Buttons:Code:StartThe code for the start button is pretty simple. Basically we would like to disable the start button enable the stop button and call the thres to start
    Code:

    private void btnStart_Click(object sender, EventArgs e)
    {
    btnStart.Enabled = false
    ;
    btnStop.Enabled =
    true
    ;
    thread1.RunWorkerAsync();
    }


    Now your DoWork event will fire.

    Writing messages to the text box
    If you call the TextBox’s .Text property to send messages you will get the following error:
    Cross-thread operation not valid: Control “txtOutInfo” accessed from a thread other than the thread it was created on.
    In order to acess the textbpx Text Propety you need to use a delegate

    Code:
    private void SetText(string text)
    {
    if (this.OutInfo.InvokeRequired)
    {
    // InvokeRequired required compares the thread ID of the calling thread to the thread ID of the creating thread. If these threads are different, it returns true.
      SetTextCallback stc =
     new SetTextCallback(SetText);   this.Invoke(d, new object[] text });}
    else
    {
       this
    .txtOutInfo.Text += text;
       this
    .txtOutInfo.SelectionStart = OutInfo.Text.Length;
       OutInfo.ScrollToCaret();
    }
    }
    And you now have messages:

     

    Now that you set up your Kernel you can implement the import function to update the database

     

    Please leave comments or questions.

    O.

  • Cross Browser Development Tips and Tricks

    IE6! IE7!  Safari!  Opera! FireFox! OH MY!!! Developing for today multiple browsers can be a nightmare. In this article I go over some tips and some general guidelines on how to make Cross Browser Development as easy as possible.

    Overview

    If we look at the market share of today's browsers for the last year we get something like this:

    IE Internet Explorer
    Fx Firefox
    Moz The Mozilla Suite (Gecko, Netscape)
    S Safari
    O Opera

    Browser Statistics Month by Month

    2007 IE7 IE6 IE5 Fx Moz S O
    December 21.0% 33.2% 1.7% 36.3% 1.4% 1.7% 1.4%
    November 20.8% 33.6% 1.6% 36.3% 1.2% 1.8% 1.6%
    October 20.7% 34.5% 1.5% 36.0% 1.3% 1.7% 1.6%
    September 20.8% 34.9% 1.5% 35.4% 1.2% 1.6% 1.5%
    August 20.5% 35.7% 1.5% 34.9% 1.3% 1.5% 1.7%
    July 20.1% 36.9% 1.5% 34.5% 1.4% 1.5% 1.9%
    June 19.7% 37.3% 1.5% 34.0% 1.4% 1.5% 1.8%
    May 19.2% 38.1% 1.6% 33.7% 1.3% 1.5% 1.7%
    April 19.1% 38.4% 1.7% 32.9% 1.3% 1.5% 1.6%
    March 18.0% 38.7% 2.0% 31.8% 1.3% 1.6% 1.6%
    February 16.4% 39.8% 2.5% 31.2% 1.4% 1.7% 1.5%
    January 13.3% 42.3% 3.0% 31.0% 1.5% 1.7% 1.5%
                   

    A couple of things that we can conclude from this chart:

    1. IE 6 is still the number one browser(avg over 12 months)
    2. We can ignore Opera and Mozilla as there market share is either decreasing or staying at the low end
    3. IE7 is gaining ground
    4. FireFox is getting hugely popular
    5. While Safari is not that large of a market share Mac users are begining to embrace it AND a windows version was just released.

    So how does one begin development when there are so many browsers out there?

    Here are some tips some rules and some hacks that can make you life easier:

    1. Download the Latest Version of Firefox, Safari and Upgrade to IE7.

    On your development system you should have the latest FireFox, Safari(for Mac users) and IE7. IE7 is going to get the most complaints from developers but it is essential that you upgrade because IE7 is gaining ground and IE6 is slowly dying(yay!!). Having these three browsers(plus I will show a way to get IE6 on your machine too, more on that later) will make sure that you see is what over 90% or more of the internet will also see.

    2. Download Microsoft Virtual PC for IE6 Development

    Like I said before, you can work with both IE7 and IE6 on the same system its just that you have to run IE6 on a virtual PC. Luckily for us Microsoft offers a free version of virtual PC that represent Windows Xp with IE6 running on it. Downloading and installing that will allow you to have IE7 on your main environment and IE6 via virtual PC!! Click on the link below to get Virtual PC. Click on the screen shot to see IE6 and IE7 working side by side:



    Get Microsoft Virtual PC

     

     

    3. Download Firebug(FireFox) and Web Developer(FireFox) and IE Developer Toolbar(IE6 and IE7)

    Firebug is the most important add on because it allows you to adjust the css live then change your templates as you make changes. IE Developer Toolbar allows you to inspect elements in IE7 and IE6 but you can not make live edits. Still they will Greatly help you in solving CSS and alignment issues.
    Get them Here:
    Web Developer(FF)
    FireBug(FF)
    IE Developer Toolbar

     

    4. Always Develop for FireFox/Safari First...

    Firefox has the greatest amount of tools to develop with. Safari will render almost exactly like Firefox so developing for one should be compatible with the other. The second reason is that there are plenty of Hacks and workarounds for IE that are not available for FireFox.
     

    5. ... Then Develop for IE6 and IE7

    After you finish developing for FF you can now begin your IE6 and IE7 development. I suggest you start with IE7 then IE6. The reason being is that IE6 will run slowly in the Virtual PC so you only want to make final adjustments using...

    6. Use Conditional statement for IE6 and IE7

    After you completed your developement in FireFox and you bring up your page in IE6/7 you should notice some style differences. Using Conditional statements to load other CSS stylesheet for IE7/6 will keep your CSS valid and since conditional statements only work in IE, it will isolate IE. To do this add a second and third Stylesheet called IE7.css and IE6.css and load them after you main stylesheet.. In these style sheets you should overwrite any style that are not working in Firefox. Here is how the Stylesheet should be set up in your<head> tag

    <head>
    <link rel="stylesheet" type="text/css" href="StyleSheet.css" />
    <!--[if IE 7]>
    <link rel="stylesheet" type="text/css" href="IE7.css" />
    <![endif]-->
    <!--[if IE 6]>
    <link rel="stylesheet" type="text/css" href="IE6.css" />
    <![endif]-->
    </
    head>



    7. Only use hacks as a last resort ... and if you do use them separate them out

    There comes a point where the clock is ticking and you need the website done yesterday. While I don't condone using hacks some times it is a necessity to get something to work in all browser. If you do use hacks follow these two rules

    1. Separate the hacks from the main styling
    2. Use cascading hacks and label them

    For example you have a class called table width. In Firefox it looks good but in IE7 its too wide and in IE 6 its too short. Here is a diagram of how the hacks work.

    Since you coded for FireFox you should not need to hack it.

    If you want a style to only be seen by IE7 and IE6 place a # in front of the style

    For IE6 only place a _ in front of the style.

    So if your main styling code for a class tablewidth looks like his:

     .tablewidth
    {
           color:black;
           padding:0px 5px 3px 2px;
           width:532px;
    }

    remove the problematic style  and create a new section below the original:

     .tablewidth
    {
           color:black;
           padding:0px 5px 3px 2px;

    }

    /*Hacks for tablewidth class*/

     .tablewidth
    {
       width:532px;  /*Firefox/Safari will read this*/
       #width:530px; /*IE7 and IE6 can only see this  */
       _width:520; /*Only IE6 can read this */
    }

    Coding the style sheets in this way will make you code much more readable and make you hacks easier to find and remove if you solve the problem or rework using conditional statements


     

    I hope you find this article useful, please feel free to leave me comments and questions

     

  • Top 5 programming languages you should know in 2008

    Programming languages, run the web. I am always asked "Which programming language is the best to learn?" to which I counter " If you only know one, then your in serious trouble." This got me thinking on what programming languages should a programmer know to maximize his talent and marketability. Below is the top five languages that every programmer should know:


     5. Ruby on Rails

    Why you should learn it:
    Cause it is the future. If you want to build a website writing only 8 lines of code Ruby on Rails(RoR) is the language for you. There has always been talk of Object Oriented Programming(OOP) and Ruby on Rails is OOP in its purest form.
    Why it is number 5: Cause it is still in infancy and it does not have a debugger or a true IDE. Also its has a STEEP learning curve and its hard to understand how each component is put together
    Resources: Top 12 Ruby on Rails Tutorials

     


    4. MYSQL/Microsoft SQL(T-SQL) 

    Why you should learn it:
    Static pages are dead. Almost any reputable site has a database as a back end. The abilty to program Stored Procedures as well as simple task as creating a table, is a MUST if you are to be a complete programmer. Whether its Sql Server or MySql it is imperative that you learn a Structured  Query Language.
    Why it is number 4: In some cases you can get by, by not knowing a SQL language, in some companies they have dedicated Database programmer who will do the work for you. In general,especially in 08' you need to know how some database programming.
    Resources: Top Tutorial on MysqlTutorial on MS Sql 


    3. JavaScript/AJAX

    Why you should learn it:
    Ajax (Asynchronous JavaScript and XML) is the new buzz word in the industry. Why I included JavaScript also is you can not do one with out knowing the other. Ajax in essence is a technique of updating "regions" on a web page instead of updating the page on a post back. Ajax is the future of web and every programmer should learn it for 2008
    Why it is number 3: Cause you cant program a web page in Ajax/JavaScript alone(at least not yet). You still need a underling technology that the web page runs on(LAMP,ASP.NET, etc). Ajax is still a great tool/method to create cool effects and functionality.
    Resources:Tutorial on AJAX,Tutorial on Javascript


    2. PHP

    Why you should learn it:
      The old master, PHP (which surprisingly stand for Personal Home Page) is still going strong. PHP in association with LAMP(Linux Apache MySql PHP) is a effective cheap and efficient way to program websites. You can have a entire infrastructure built of free cheap software. Many reputable businesses and large companies are now adopting LAMP as a standard. Not only that there is a wealth of CMS and Community orientated software that are available only for PHP(Drupal,Joombla). There are many availiable free library and a wealth of info avaliable for PHP.
    Why it is number 2: Lack of standardization. Ask 4 different PHP programmer of a way to accomplish as task, and you might get 5 different answers. While debuggers and IDE's do exist lack, of standardization hurts the technology. Overall you can create cheap,
    Resources:PHP Tutorial


    1. C#

    Why you should learn it:
    Quite simple it simple, powerfully and extensible. Its IDE(Visual Studio 2008) is second to none. You can easily create both web applications and windows application with out learning a new language. Integrating with any database is easy and there are plenty of libraries and systems (Community Server) that use C#. Used in conjunction with ASP.Net C# can preform any task that any other languages can do WITH a better and usable interface.

    Why it is Number 1: Quite frankly its the easiest most extensible language out there. Some would say C# is nothing but a next generation VB. I disagree I think it is the next generation of C++ which was universally loved. C# programmers also tend to make the most in the job market.
    Resources: C# Tutorials

     

    So take some time this year and learn something new. For me my goal is to improve my PHP skills. Please feel free to comment or email me with any questions.


     

  • Adding a Confirm Javascript PopUp with a image to a ASP.NET GridView AND Update the database

    After hours of searching thru pages and pages of code I could not find a single example of code that did exactly what I wanted. Here is the scenario:

    I want a GridView in Asp.net to display a image that will fire some Javascript confirming that I want to delete the row. If I press OK the a Asp.net function will fire that will delete the user. If I click cancel nothing will happen.

     So for everybody looking for this code I am going to show you EXACTLY how to do it step by step:

    Setting up the GridView Control

    1. Create a new web site in Asp.net(or use a existing one) and drop in your Gridview Control

    2. Click on the Task icon and set up your datasource( in this example I am using the Northwind Database and accessing the customers table)

    3. Add a Command field. I moved mine to the top.

    Add a command field

    4. Set the "Show Delete Button" to true

    Set Show Delete Button to True

    5. Press OK ( you can also set Show CancelButton to True) Now we need to setup a bounding event.

    6.Right Click on the GridView Control and choose Properties

    7. Click on the Events button(the lighting bolt) and double click on the "RowDataBound" event

    Now we are set up for code

    Lets overview what we want. Want some Javascript to be called with a OK and Cancel button and we want some sort of image representing the delete button. First we are going to find the delete control, and second we are going to cast it as a LinkButton(I will explain why shortly) and third we are going to add some JavaScript to confirm that we want to delete a customer:

    1. You should now be in the Code behind page and at the Function:protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e) if not press F7 and find the function

    2. First we find the control, then we cast it to a link button and then we use the "OnClientClick" property of the link button to set the JavaScript. Finally we use the "Text" property to add a image to the link button: Here is the code

    if (e.Row.RowType == DataControlRowType.DataRow)
    {
    LinkButton deleteButton = (LinkButton)e.Row.Cells[0].Controls[2];  //<-- we are casting control 2 my delete control link to a LinkButton
    deleteButton.OnClientClick = return confirm('Delete this Record (" + ((DataControlFieldCell)e.Row.Cells[2]).Text + ")?')"; // <-- here we add the javascript on the onclick event

    deleteButton.Text = "<img src=\"icon_delete.gif\"/>"; //<-- finally we add the image to the text element

    }

    3. If we compile and run the code and look at the source we have the basis of what we want:

     <table cellspacing="0" rules="all" border="1" id="GridView1" style="border-collapse:collapse;">
      <tr>
       <td><a href="doPostBack('GridView1','Edit$0')">Edit</a>&nbsp;<a onclick="
    return confirm('Delete this Record (Alfreds Futterkiste)?');" href="doPostBack('GridView1','Delete$0')"><img src="icon_delete.gif"/></a></td><td>ALFKI</td><td>Alfreds Futterkiste</td><td>Maria Anders</td><td>Sales Representative</td><td>Obere Str. 57</td><td>Berlin</td><td>&nbsp;</td><td>12209</td><td>Germany</td><td>030-0074321</td><td>030-0076545</td>
      </tr>

    In the browser it looks like this:

    We now have a image button that pulls this up when clicked

    Delete

    Updating the database

    We have a Confirm delete pop up but now we need to have a way to update the database when the user presses "OK" and do nothing if the user presses "Cancel

    1. Let go back to the Gridview and right click on it and select properties and go to the event tab again

    2.. Now Double click on the "RowCommand" Event


    3. Now we need to find the row that was clicked and what command was called (NOTE: Remember I have a Cancel button as well as a delete button so it is useful to know what command was pressed) Here is the simple code:

    protected void GridView1_RowCommand1(object sender, GridViewCommandEventArgs e)
    {
    // get the row index stored in the CommandArgument property
    int index = Convert.ToInt32(e.CommandArgument);
    // find the command to execute
    string command = e.CommandName;
    if (command == "Delete")
    {
    //call delete function
    }

    }

    4. Now you can write your delete code

    Now you might ask "What happens if cancel is pressed?" remember we have a return  on the Javascript so if it returns "false" or cancel the RowCommand Event will never fire.

    I hope this post is helpful, please leave any comment or questions.

    Update: I added the code in the downloads page if you want to review the project. Get if from here