Wednesday, August 19, 2015

PHP Profiling Using Xdebug and Kcachegrind

Xdebug's Profiler is a powerful tool that gives you the ability to analyze your PHP code and determine bottlenecks or generally see which parts of your code are slow and could use a speed boost. The profiler in Xdebug 2 outputs profiling information in the form of a cachegrind compatible file. This allows you to use the KCacheGrind tool (Linux,) to analyse your profiling data. 
Xdebug profiler is incorporated in the Xdebug tool. Therefore you first need to download, install, and enable Xdebug itself and after that enable the profiling functionality within it.

Install x-debug through apache


sudo apt-get install php5-xdebug

Enabling Xdebug integration with the PHP engine

Once xdebug is installed, you can enable the xdebug(profiler) to work with PHP by adding following lines at the end of php.ini file.








[xdebug] 
zend_extension="/usr/lib/php5/20121212/xdebug.so"  ;path to xdebug.so
xdebug.profiler_append = 0
xdebug.profiler_enable = 0
xdebug.profiler_enable_trigger = 1
xdebug.profiler_output_name = cachegrind.out.%t-%s
xdebug.profiler_output_dir = "/home/bipen/lf/fhf_files/codeprofiling"
You can run this  command yo find the path to xdebug.so

find / -name 'xdebug.so' 2> /dev/null
Replace this path in "zend_extension= ...."

Xdebug Settings
  1. xdebug.profiler_append:
    Type: integer, Default value: 0
    Setting it to 1 will not overwrite the exisitng profiler file when a new request is made but append the new profiling in same file.
     
  2. xdebug.profiler_enable:
    Type: integer, Default value: 0
    Setting it to 1 will enable xdebug profiler which creates a file in the "profiler_output_dir" directory but If you want to selectively enable the profiler, set "profiler_enable_trigger" as 1
     
  3. xdebug.profiler_enable_trigger
     Type: integer, Default value: 0When this setting is set to 1, you can trigger the generation of profiler files by using the XDEBUG_PROFILE GET/POST parameter, or set a cookie with the name XDEBUG_PROFILE. If you want to profile a particular url you can append "?XDEBUG_PROFILE=1"  at the end.
    eg: http://somedomain.com/test?XDEBUG_PROFILE=1  (make sure xdebug.profiler_enable is set to 0)

  4. xdebug.profiler_output_name
    Type: string, Default value: cachegrind.out.%p This setting determines the name of the file that is used to dump traces into. The setting specifies the format with format specifiers, very similar to sprintf() and strftime(). There are several format specifiers that can be used to format the file name.
     
  5. xdebug.profiler_output_dir
    Type: string, Default value: /tmp The directory where the profiler output will be written to, make sure that the user who the PHP will be running as has write permissions to that directory. 

Once all of this settings is set,  run any project in your browser and this should generate a profiler file in above mentioned directory. Keep it mind, "profiler_enable"  set to 1 will profile all of the PHP process everytime it  runs  so you might end up having a lots and lots of profiler files in your system.

Installing KCACHEGRIND

KCachegrind is a tool used for profile data visualization. Visit this link for more details (http://kcachegrind.sourceforge.net/html/Documentation.html)

sudo apt-get install kcachegrind

References:

Monday, May 25, 2015

missing mcrypt – Fatal Error: Undefined function mcrypt_encrypt()! in Ubuntu 13.10/14.04

I came across this problem when I upgraded my Ubuntu to 14.04. I have used php-mycrypt in one of my project which was working fine until my ubuntu got upgraded and now when I try to access my project I get this Fatal Error
Fatal Error: Undefined function mcrypt_encrypt()
The solution looks simple but it took me ages to figure out and after a lot of googling around (most of the solution provided didn't help me at all ) so I thought I will share this hoping that you guys end up here quickly and don't have to spend much of your time (like I did ) :):) and hoping this will help you guys.

So, without wasting much of your time. Let me begin, First thing to do is see if you have installed php5-mcrypt (like everyone does), you can do that by:
sudo apt-get install php5-mcrypt
It should install mycrypt and if already installed, you will get the following message:
Reading package lists... Done
Building dependency tree       
Reading state information... Done
php5-mcrypt is already the newest version.
0 upgraded, 0 newly installed, 0 to remove and 13 not upgraded.
Looks good till now but wait a second, I still get that undefined fatal error. so what now,
Secondly,
see your ini file is in correct path. If not then move it (not neccessary if it is already there)
$mv /etc/php5/conf.d/mcrypt.ini /etc/php5/mods-available/
Thirdly,
Enable mcrypt module. run the following command to enable it:
sudo php5enmod mcrypt
Restart Apache
sudo service apache2 restart
Try it out now And HOlA!!!!! IT works.

Hope it helped. Feel free to comment or you have any concerns or you know any other way :). Let us help each other and yes Happy coding.

jQuery Best Pratices

  1.  jQuery Files
    a) Try to use Jquery CDN where possible.                 
    <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script>window.jQuery || document.write('<script src="js/jquery-2.1.1.min.js" type="text/javascript"><\/script>')</script>
        Implement a fallback to locally hosted jQuery file of same version in-case CDN is not working.(as above) 
    b) DO NOT use jQuery version 2.x if you support Internet Explorer 6/7/8.
    c) If you are using other libraries like Prototype, MooTools, Zepto etc. that uses `$` sign as well, try not to use `$` for calling jQuery functions and instead use `jQuery` simply or use `$.noConflict()`.
     
  2.  jQuery Variable
    a) Better to start with  `$` while naming jQuery variable so it will be easy to understand and later on manipulate.
    var $someDiv = $("#someDiv"); // var $someDiv since it is a jQuery object
    var string = "some string"//not a jQuery object
    b) Always cache jQuery selectors object to a variable for reuse.
    var $someDiv = $("#someDiv");
    $someDiv.click(function(){
       alert('clicked');
    });
    c) It is recommended to use Camel Case for naming Variable.
  3. Selectors
    a) Use ID selector whenever possible, since it uses javascript `document.getElementById()` selectors which is faster.
    b) Don't use the element type in your selector when using class selector. (for performance comparison click on : http://jsperf.com/jqeury-selector-test
    var $something = $("div.something"); // SLOW
    var $something = $(".something"); // FAST
    c) Use `.find()` selector. The `.find()` approach is faster because the first selection is handled without going through the Sizzle selector engine.          
    // Fast:
      $( "#container div.robotarm" );
    // Super-fast:
      $( "#container" ).find( "div.robotarm" );
    // BAD, goes through Sizzle selector engine
      var $productIds = $("#products div.id");
    // GOOD, #products is already selected by document.getElementById() so only div.id needs to go through Sizzle selector engine
      var $productIds = $("#products").find("div.id");
    d) Be specific on the right-hand side of your selector, and less specific on the left.  
    // Unoptimized
       $("div.data .gonzalez");
    // Optimized
       $(".data td.gonzalez");
    e) Avoid Excessive Specificity. (for performance comparison click on : http://jsperf.com/avoid-excessive-specificity)
    $(".data table.attendees td.gonzalez");
    // Better: Drop the middle if possible.
    $(".data td.gonzalez");
    f) Give your Selectors a Context.
    // SLOWER because it has to traverse the whole DOM for .class
    $('.class');
    // FASTER because now it only looks under class-container.
    $('.class''#class-container'); //this uses `.find()` selector internally.
    g) Avoid Universal Selectors. More Info 
    $( ".buttons > *" ); // Extremely expensive.
    $( ".buttons" ).children(); // Much better.
    h) Avoid Implied Universal Selectors. When you leave off the selector, the universal selector (*) is still implied.
    $('div.someclass :radio'); // BAD
    $('div.someclass input:radio'); // GOOD
    i) Don’t Descend Multiple IDs or nest when selecting an ID. ID-only selections are handled using document.getElementById() so don't mix them with other selectors.
    $('#outer #inner'); // BAD
    $('div#inner'); // BAD
    $('.outer-container #inner'); // BAD
    $('#inner'); // GOOD, only calls document.getElementById() 
  4. DOM Manipulation
    a) Always detach any existing element before manipulation and attach it back after manipulating it. This is reduce the Reflow and Repaint of browser and increase performance drastically or use `documentfragment`.
    var $myList = $("#list-container > ul").detach();
    //...a lot of complicated things on $myList
    $myList.appendTo("#list-container");
    b) Use string concatenation or `array.join()` over `.append()`. (for performance comparison click on : http://jsperf.com/jquery-append-vs-string-concat)
    // BAD
    var $myList = $("#list");
    for(var i = 0; i < 10000; i++){
        $myList.append("<li>"+i+"</li>");
    }
    // GOOD
    var $myList = $("#list");
    var list = "";
    for(var i = 0; i < 10000; i++){
        list += "<li>"+i+"</li>";
    }
    $myList.html(list);
    // EVEN FASTER
    var array = []; 
    for(var i = 0; i < 10000; i++){
        array[i] = "<li>"+i+"</li>"
    }
    $myList.html(array.join(''));
    c) Make sure you check for the element in DOM before manipulating it if you are not sure about that element.
    // BAD: This runs three functions before it realizes there's nothing in the selection
    $("#nosuchthing").slideUp();
    // GOOD
    var $mySelection = $("#nosuchthing");
    if ($mySelection.length) {
       $mySelection.slideUp();
    }

  5. Events
    a) Use only one `document.ready` handler per page. It makes it easier to debug and keep track of the behavior flow.
    $(document).ready(function(){.....})
    //OR
    $(function(){....}) //short hand for document.ready function
    b) DO NOT use anonymous functions to attach events. Anonymous functions are difficult to debug, maintain, test, or reuse.
    // BAD
    $("#myLink").on("click", function(){...});
    // GOOD
    function myLinkClickHandler(){...}
    $("#myLink").on("click", myLinkClickHandler);

    c) Avoid Inline Javascript in HTML markup, these are debugging nightmares. Always bind events with jQuery to be consistent so it's easier to attach and remove events dynamically.
    //BAD
    <a id="myLink" href="#" onclick="myEventHandler();">my link</a>
    //GOOD 
    $("#myLink").on("click", myEventHandler);
    d) When possible, use custom namespace for events. It's easier to unbind the exact event that you attached without affecting other events bound to the DOM element.
    $("#myLink").on("click.mySpecialClick", myEventHandler); // GOOD
    // Later on, it's easier to unbind just your click event
    $("#myLink").unbind("click.mySpecialClick");
    e) Use event delegation (for dynamically added element) when you have to attach same event to multiple elements. Event delegation allows us to attach a single event listener, to a parent element, that will fire for all descendants matching a selector, whether those descendants exist now or are added in the future.
    $("#list a").on("click", myClickHandler); // BAD, you are attaching an event to all the links under the list.
    $("#list").on("click""a", myClickHandler); // GOOD, only one event handler is attached to the parent.
  6. Ajax
    a) DO NOT use http requests on https sites. Prefer schemaless URLs (leave the protocol http/https out of your URL)
    b) DO NOT put request parameters in the URL, send them using data object setting.
         
    // Less readable...
    $.ajax({
       url: "something.php?param1=test1&param2=test2",
       ....
    });
    // More readable...
    $.ajax({
       url: "something.php",
       data: { param1: test1, param2: test2 }
    });
    c) Try to specify the dataType setting so it's easier to know what kind of data you are working with.
    d) Use Delegated event handlers for attaching events to content loaded using Ajax. Delegated events have the advantage that they can process events from descendant elements that are added to the document at a later time (example Ajax).
    $("#parent-container").on("click""a", delegatedClickHandlerForAjax);
    e) Use Promise interface: 
    $.ajax({ ... }).then(successHandler, failureHandler);
    // OR
    var jqxhr = $.ajax({ ... });
        jqxhr.done(successHandler);
        jqxhr.fail(failureHandler);

    Sample Ajax Template:
    var jqxhr = $.ajax({
                   url: url,
                   type: "GET"// default is GET but you can use other verbs based on your needs.
                   cache: true// default is true, but false for dataType 'script' and 'jsonp', so set it on need basis.
                   data: {}, // add your request parameters in the data object.
                   dataType: "json"// specify the dataType for future reference
                   jsonp: "callback"// only specify this to match the name of callback parameter your API is expecting for JSONP requests.
                   statusCode: { // if you want to handle specific error codes, use the status code mapping settings.
                      404: handler404, // handler404() function
                      500: handler500  // handler500() function
                   }
               });
    jqxhr.done(successHandler); //successHandler function
    jqxhr.fail(failureHandler); // failHandler function
  7. Effects and Animations
    a) Adopt a restrained and consistent approach to implementing animation functionality.
    b) DO NOT over-do the animation effects until driven by the UX requirements.
    c) Try to use simple `show/hide`, `toggle and slideUp/slideDown` functionality to toggle elements.
    d) Try to use predefined animations durations of "slow", "fast" or 400 (for medium).
     
  8. Plugins
    a) Always choose a plugin with good support, documentation, testing and community support.
    b) Check the compatibility of plugin with the version of jQuery that you are using.
    c) Any common reusable component should be implemented as a jQuery plugin. link to http://stefangabos.ro/jquery/jquery-plugin-boilerplate-revisited/  jQuery Plugin Boilerplate code.
     
  9. Chaining
    a) Use chaining as an alternative to variable caching and multiple selector calls.        
    $("#myDiv").addClass("error").show();
    b) Whenever the chain grows over 3 links or gets complicated because of event assignment, use appropriate line breaks and indentation to make the code readable.
    $("#myLink")
           .addClass("bold")
           .on("click", myClickHandler)
           .on("mouseover", myMouseOverHandler)
           .show();
    For long chains it is acceptable to cache intermediate objects in a variable. 
  10. Miscellaneous
    a) Use Object literals for parameters.
    $myLink.attr("href""#").attr("title""my link").attr("rel""external"); // BAD, 3 calls to attr()
    // GOOD, only 1 call to attr()
    $myLink.attr({
         href: "#",
         title: "my link",
         rel: "external"
    });
    b) Do not mix CSS with jQuery.
    //BAD
    $("#mydiv").css({'color':red, 'font-weight':'bold'}); 
    //GOOD
    .error { color: red; font-weight: bold; }
    $("#mydiv").addClass("error");
    c) DO NOT use Deprecated Methods. It is always important to keep an eye on deprecated methods for each new version and try avoid using them. Checkout http://api.jquery.com/category/deprecated/ for a list of deprecated methods. Some of which are:
    .live() (Deprecated > Deprecated 1.7 | Removed),
    .load() (Deprecated > Deprecated 1.8 | Events > Document Loading),
    .selector Deprecated > Deprecated 1.7 | Removed
    d) Combine jQuery with native JavaScript when needed. (performance comparision : http://jsperf.com/document-getelementbyid-vs-jquery/3
    $("#myId"); // is still little slower than...
    document.getElementById("myId");
  11. Resources
    jQuery Performance: http://learn.jquery.com/performance/
    jQuery Learn: http://learn.jquery.com
    jQuery API Docs: http://api.jquery.com/
    jQuery Coding Standards and Best Practice: http://www.jameswiseman.com/blog/2010/04/20/jquery-standards-and-best-practice/
    jQuery Cheatsheet: http://lab.abhinayrathore.com/jquery-cheatsheet/
    jQuery Plugin Boilerplate: http://stefangabos.ro/jquery/jquery-plugin-boilerplate-revisited/Stackoverflow question: http://stackoverflow.com/questions/tagged/jquery