Showing posts with label php tutorial. Show all posts
Showing posts with label php tutorial. Show all posts

Monday, November 22, 2010

XDebug for developing, debugging and profiling PHP


XDebug is one of the essential PHP extensions for PHP developers. The name is a bit misleading, as it implies that it is just a debugging tool. This can put people off, since getting the debugger to work with your personal editor requires an understanding of networking, and can often be confusing. Even if you can't immediately get XDebug to work as a debugger, it is still valuable as a stack trace tool, or as a color coded replacement for PHP's var_dump, or as a code coverage analysis tool, and most importantly as a profiler. In this tutorial I'll attempt to cover installation, and most of XDebug's standard features.

Install XDebug

Anyone who spends any time doing PHP development soon finds that PHP is not a one size fits all world. Thanks to its efforts to be a portable and extensible platform, PHP offers developers a wide array of platforms, installation methods, and configurations. Since XDebug needs to play within the ecosystem of PHP, there are a variety of different ways you can install it including compiling it from source.

The important thing to keep in mind is that XDebug is something you want installed on your development server, not on your production server! For that reason, I'm not going to cover compiling from source. All the installation options are covered in the XDebug manual.

For most people, the easiest way to install XDebug is to use PEAR/PECL. On a unix system that involves running pecl install.

# pecl install xdebug

Upon completion, you can check that everything has installed correctly.

debian:~# pecl list
Installed packages, channel pecl.php.net:
=========================================
Package Version State
xdebug 2.0.5 stable

On a Debian system, the build process included adding an ini file in an include directory that php utilizes to configure its modules, and I did not need to make further adjustments -- just restarted apache. On a 64bit Centos 5.5 install, the php.ini needed to be manually updated. In order to find the location of the xdebug.so, you can run pecl list-files.

[root@localhost ~]# pecl list-files xdebug
Installed Files For xdebug
==========================
Type Install Path
doc /usr/share/pear/doc/xdebug/contrib/tracefile-analyser.php
doc /usr/share/pear/doc/xdebug/contrib/xt.vim
doc /usr/share/pear/doc/xdebug/Changelog
doc /usr/share/pear/doc/xdebug/CREDITS
doc /usr/share/pear/doc/xdebug/LICENSE
doc /usr/share/pear/doc/xdebug/NEWS
doc /usr/share/pear/doc/xdebug/README
src /usr/lib64/php/modules/xdebug.so

When you run the pecl install you'll see an erroneous message indicating that you should add an extension=xdebug.so to your php.ini. IGNORE THIS!!!
You actually need to load XDebug using either:

; Enable xdebug
zend_extension="/usr/lib64/php/modules/xdebug.so"

--or if you're setup with the threaded environment that has enabled "thread safety" then:

; Enable xdebug
zend_extension_ts="/usr/lib64/php/modules/xdebug.so"

The cleanest way to set this up under Centos is to create a file in the /etc/php.d directory named xdebug.ini. You can also just manually add the lines above to your php.ini file. The comment "; Enable xdebug" isn't necesssary but it's helpful for documentation purposes to have it, so why not?
If you've followed these instructions and you still don't see xdebug in your phpinfo() page, make sure you have permanently disabled selinux, as it can interfere with the ability for php to load the XDebug module.

Once you've installed XDebug, an XDebug section will be visible in the phpinfo() page, along with a list of default settings.

var_dump()


One of the first things that XDebug will do by default is replace php's var_dump() with a nicer version that is also configurable in a variety of ways.
In this example, I've inserted:

var_dump($mainframe); die();

--into the index.php file for the CMS joomla. The $mainframe object is the main application/controller object for Joomla, so inspecting it might be useful for understanding more about how Joomla works. Without XDebug, this is what the output looks like:

object(JSite)#2 (7) { ["_clientId"]=> int(0) ["_messageQueue"]=> array(0) { } ["_name"]=> string(4) "site" ["scope"]=> NULL ["_errors"]=> array(0) { } ["requestTime"]=> string(16) "2010-10-09 23:56" ["setTemplate"]=> string(13) "rhuk_milkyway" }


With it turned on we get this:
xdebug_vardump

XDebug adds nesting, color coding and scope identification to the output.
Consider a more complicated object:
xdebug_novardump2
Trying to make sense out of all this jumbled output isn't easy. With XDebug you can see the forest through the trees.

xdebug_vardump2

Stack Trace dump


A stack dump is what PHP spits out when you have a runtime error in your script. During development you want to have display_errors turned on, so you can easily see these when they occur. Vanilla PHP might show you something like:

Fatal error: Uncaught exception 'Zend_Controller_Dispatcher_Exception' with message 'Invalid controller specified (tutorials)' in /var/sites/flingbits.com/library/Zend/Controller/Dispatcher/Standard.php:248 Stack trace: #0 /var/sites/flingbits.com/library/Zend/Controller/Front.php(954): Zend_Controller_Dispatcher_Standard->dispatch(Object(Zend_Controller_Request_Http), Object(Zend_Controller_Response_Http)) #1 /var/sites/flingbits.com/library/Zend/Application/Bootstrap/Bootstrap.php(97): Zend_Controller_Front->dispatch() #2 /var/sites/flingbits.com/library/Zend/Application.php(366): Zend_Application_Bootstrap_Bootstrap->run() #3 /var/sites/flingbits.com/public/index.php(10): Zend_Application->run() #4 {main} thrown in /var/sites/flingbits.com/library/Zend/Controller/Dispatcher/Standard.php on line 248

With XDebug, your Stack dump looks like this:
xdebug_stack1
The XDebug version is not only a lot easier to read, but it also adds profiling and memory usage information to the trace. However, there are a number of additional options you can turn on to make this even more useful.

xdebug.collect_params

This setting will provide you a variable level of information about parameters being passed. Setting this to "4" gives you the maximum amount of parameter information available.

xdebug.collect_params=4


xdebug.show_local_vars=1

This is a kitchen sink setting that will dump out every variable in the local scope. In a smaller application or when confronted with a particularly confusing problem, this might be useful, but in most cases where you have a script of any sophistication, it simply produces too much output.

Dumping superglobals

You can add some or all of the various superglobals to your stack trace, by setting the xdebug.dump.SUPERGLOBALNAME=*.
For example:

xdebug.dump.SESSION=*
xdebug.dump.COOKIE=*
xdebug.dump.GET=*
xdebug.dump.POST=*
xdebug.dump.FILES=*
xdebug.dump.REQUEST=*
xdebug.dump.ENV=*
xdebug.dump.SERVER=*

Most of the time, you will probably want to limit the output to a handful of commonly useful variables, so instead of setting the variable to the wildcard '*', you can instead pass a list of the specific variables you are interested in.
For example:

xdebug.dump.SERVER=SCRIPT_FILENAME,REQUEST_METHOD,QUERY_STRING,HTTP_COOKIE,REMOTE_ADDR


Profiling


The XDebug profiler outputs "cachegrind compatible files" that can be analyzed with a variety of tools, depending on your platform. If you're developing on a linux workstation use kcachegrind, or on windows wincachegrind.

The best way to enable profiling is to set XDebug so that you can pass a parameter to the script via a GET, POST or COOKIE that will enable it. There's also a setting that defines the name of the cachegrind file(s) generated. I recommend these settings, and by default your files will be deposited in the /tmp directory of the server.

;profiling
xdebug.profiler_enable_trigger=1
xdebug.profiler_output_name=cachegrind.out.%s.%t

Now you can selectively trigger profiling by passing a GET param in the URL:

http://www.gizlocal.com/?XDEBUG_PROFILE

Once the script has run, you should find the profile output file in your temp directory. The file will be namedcachegrind.out.{path_and_filename}.{timestamp}

Using these settings will allow you to generate multiple profilings for the same script, as well as allowing you to easily identify the script that actually generated the profiling data.


debian:/tmp# ls -lath | grep cachegrind*

... 4.5M 2010-11-16 13:04 cachegrind.out._var_sites_flingbits.com_public_index_php.1289941492


Once you have a profiling data file, you will need to load it into an analysis tool. There are analysis tools available for most common operating systems, although the features of the various tools differs. For an Xwindows Linux workstation, KCachegrind provides the timing and call data as well as graphical visualizations like the "Call Graph" screen. WinCacheGrind is a native windows application which doesn't provide graphs, but does show the calls and timings, and allows you to sort the profile data in a variety of ways. Here's a screenshot showing the functions which take the most time.

xdebug_profile

Regardless of the tool, your primary goal is to determine which blocks of code are taking the most time. The analysis tool will show you how many times each function was called, along with aggregate and average execution times. Often you will have functions or methods that call other functions. The local time is totalled seperately from the cumulative time so you can determine where the majority of the time is being spent.

Debugging


Getting the XDebug remote debugger to work with your favorite IDE will probably require looking up configuration instructions for your IDE. These settings are typical, and reflect the process of setting things up to work with Eclipse PDT.
Remember that whenever you make changes to any of these serverside settings, in the php.ini or an included .ini, you must restart Apache!

The first thing you need to do is configure XDebug on your server to turn on remote debugging support. While a number of these settings are also the default it doesn't hurt to include them, in case you need to make tweaks.

;Debugger
xdebug.remote_enable=1
xdebug.remote_mode=req
xdebug.remote_port=9000
xdebug.idekey=ECLIPSE_DBGP
xdebug.remote_handler=dbgp
xdebug.remote_host=10.1.0.2

Reviewing these settings:
-- you need to enable the debugger using xdebug.remote_enable=1.
-- The xdebug.remote_port is the port the debugger will use to connect back to your IDE once the debugging session is started. It defaults to port 9000.
-- xdebug.idekey needs to be set to whatever your IDE will use to instantiate the session. This gets passed as a url parameter by the eclipse debugger as ?XDEBUG_SESSION_START=. For Eclipse with PDT, the session id will be ECLIPSE_DBGP. For other IDE's or editors that support XDebug this could very well be something different. Ultimately it is an identification mechanism, which simply has to be agreed upon for the editor to connect to XDebug. When everything is setup correctly, you can expect to see something like this in the browser URL when your eclipse debug sessions starts.

http://www.gizlocal.com/?XDEBUG_SESSION_START=ECLIPSE_DBGP&KEY=12900687508406


-- xdebug.remote_handler specifies the debug protocol, which in this case should be dbgp.
-- Last but not least, the xdebug.remote_host needs to be an IP address for your workstation that can be reached by the server. If for example, your workstation is behind a NAT firewall, you'd have to setup a port forward rule for your workstation that forwards port 9000 traffic back to your workstation. If you're using a WAMP or virtual server environment using VMware or Sun Virtualbox, then chances are this is going to be an internal IP address like the one I included in my example. I highly recommend using a virtual server for your development environment.
If you're not sure how to do this, I have a detailed 2 part article on setting up your own virtual Centos Lamp server running inside Sun Virtualbox on a PC running Windows here.


Configuring Eclipse PDT for XDebug


There are many things that can go wrong with the debugging configuration. Keep in mind that Eclipse PDT's debugger is generic and setup to support different debuggers. This section is not meant to be exhaustive, but should give you an idea of how to get started.
When the debug session starts and your workstation browser is opened, you should see a valid URL (see above) and the page should be blank. If the full page is displayed this is a good indication that you need to check your settings, and that Eclipse didn't connect to XDebug!

When configuration is complete you will open the PHP Debug perspective, and choose a debug configuration. For any specific script you want to debug, you'll need to create a Debug configuration for it. In other words, if you reach a script via a particular URL, you'll need a debug configuration unless it can be reached via another script that you have already setup. For a framework style application, you can set skip to the points you're interested in via breakpoints, but you'll need to have the files you want to set breakpoints in, open in the IDE, and then once you start the debugger, you switch to the file you want to set the breakpoint in, and choose "Run to line". It's not pretty but it works.

From the Menu choose the Run | Debug Configurations panel.

xdebug_eclipse_config1

-- When you get into this panel, give the Debug configuration a name representing the script. This will make it easy for you to choose the right config to debug. In this example, I called it "Index" because I'm debugging the index.php of this framework application.
-- Set the server debugger to XDebug.
-- Browse your project and find the script you want to debug. The script has to actually be executable.
-- Uncheck URL - Auto Generate. This is bugged in my version of Eclipse PDT, and it also seems to add slashes in the neighboring path box that you want to clear out whenever you see them.
-- Save
-- Reopen your freshly created debug configuration, and now "Add" a new PHP Server.

xdebug_eclipse_config2

-- Give this a name representing your development server that is running XDebug.
-- Enter the domain name, and provide a path if you've got an application running in a subdirectory off the site root. Leave off the closing '/'!
-- The configuration wizard will take you to the next step, which is adding at least one "Path Mapping".

xdebug_eclipse_config3

-- This maps the base location for your workspace files to the path on the server.

Ready to debug?

If everything has gone as planned you should now have a working configuration. Change to the "PHP Debug" perspective. Click on the Debug button, and choose your Debug configuration based on the name you gave it when you set the configuration up in eclipse. You can switch to the browser and should see it loaded with the proper url and the added XDebug parameters discussed previously. The screen should be blank and Eclipse should load up the debugged file into the editor, fill the variable window and set things so that you can step through the code using the "step into", "step over", and "step and return" buttons on the debug button bar.

xdebug_eclipse

Summary


XDebug is more than a debugger, even though for PHP it can be used as one. It's an invaluable development tool that will help you during the development process. Hopefully you learned more about how to set it up and start to make use of it. If you have questions or comments, reply here or make a thread in the forum.

Original Article Source:
http://www.flingbits.com/tutorial/view/xdebug-for-developing-debugging-and-profiling-php

Friday, July 3, 2009

10 Ways to Avoid Writing Crappy Code

1. Learn OOP and common OO principles

This is an absolute requirement. If you are still coding procedural, this is no small task. What are you waiting for?

1. Employ Test Driven Design

Code that is buggy or simply doesn't work at all can safely be considered "crappy code". TDD gives you the confidence that your code works, and the side effects force better and more flexible software design.
If you are not familiar with TDD yet, and this post has prompted you to try it, be warned: at first it will seem very cumbersome. What definitely will help is this piece of advice, which is at the core of Test Driven Design: don't write tests afterwards, write them first. Without going to much into the details, and somewhat simplified the general mantra is this: write a test first, make it work by writing the application code, refactor, write another test, make it work, refactor, etc etc. It's a cycle. The application code follows the test code, not the other way around.
I recommend PHPUnit. It has the most features and the largest adoption.

2. Refactor, refactor, refactor

Refactoring means "to improve the design of existing code". Making changes to code results in an increasing loss of quality of that code, this is known as "software decay". To battle this phenomenon, you have to constantly evaluate if the code hasn't lost it's quality, and look for opportunities to improve the design beyond it's original. But there's a catch. And it isn't the time that refactoring takes, if you do it properly you'll save those hours by having avoided software decay. It is the risk of change.
I can understand if you are hesitant to change code that works (at least for now). But this is where number two comes back into play: as long as you've written the right tests, you can make sure your changes don't break anything.

3. Simpler is better

Your mind should constantly be waging a battle between simplicity and flexibility. Avoid unnecessary complication.

4. Use Design Patterns

Design Patterns describe real world software design problem and solutions. Make sure you are familiar with them, buy some books. If you encounter a design problem that seems familiar take your trusty GoF and PoEAA from the shelf and look it up.

5. Don't Use Design Patterns

Once you are familiar with Design Patterns, or even just with the existence of them, it can be tempting to start sprinkling pattern implementations over your application code, just because you can. Don't. Remember a Design Pattern consists of a problem and one or more solutions to that problem. Until you have the problem, don't use the solution.

6. Accept the limitations of your language

Believe me, I know that as a programmer it is difficult to accept limitations on bending your code to your will, but trying to change the behaviour of PHP is not the solution. PHP has limitations, you'll have to live with them. If you try to "patch" them, chances are you will do more harm than good.

7. Pretend you are writing a book

It has been said that "code should be easy to read rather than easy to write". Maybe somebody else will need to understand your code at some stage. Maybe two years from now, you will revisit this code and need to re-learn it's inner workings.
Semantics, meaningful docblocks and clear execution flow are everything. Imagine reading an instruction manual without pictures, filled with meaningless abbreviations, and with the pages in arbitrary order, without page numbers. That's how someone, maybe you, will feel if you ignore this advice.

8. Peer Review

Believe it or not, you don't know everything and you aren't always right. Nobody is. Getting a "second opinion" can only improve the end result.

9. E_STRICT is your friend

Make sure your code runs properly with E_STRICT turned on. Although, if you have gotten this far, I don't think that will be a problem.

10. Create a distinction between "source code" and a "build"

Even though PHP is an interpreted language, this is an important distinction in my opinion, even though practically noone employs this in the PHP world. A build in PHP is a copy of (part of) the source code, which includes assets like HTML, CSS and JavaScript, and is stripped of anything not necessary for running the application. Maybe your build is a Phar file, or maybe you have combined some source files into a single file (like the guys at Doctrine do). Maybe you can provide different build of the same project to server different purposes..
How does this help you avoid crappy code? It allows you to have the source code and build differ, avoiding any compromises you might be tempted to make to facilitate runing or developing the application. Bonus points if you allow the user to choose between placing everything in the server document root or just a bootstrap and the static files.

There are various build tools available, personally I use PHPUnderControl, which is a patch for CruiseControl and gives you a variety of build server features. It uses Ant by default, but I also use Phing.

Thursday, July 2, 2009

10 Signs of Crappy PHP Software

Like it or not, as a professional developer, sooner or later you are going to do some customising (if you are lucky, "extending") of existing software.
If you are not familiar with the software, it is good advice to look into it before accepting the job. I had to learn that the hard way. But how do you recognize crappy applications without getting knee deep into the code? 10 pointers to identify crappy PHP software quickly...
1. The software tries to reinvent the object model, or "fix" language features.

See if you can find a class called "Object". If you find it, it's a pretty clear indication that the author is in the business of trying to reinvent the object model (most commonly because of his own lacking understanding of OO). It is safe to assume that his "fixes" won't stop there. Unplug your phone and hide under your desk.
2. The code includes user defined global variables

A search in the code for "global" or "$GLOBALS" may reveal something like this:
global $database, $my, $mainframe;
The infamous global variable. If you can tell me what those last two variables contain you are either intimate with the software I pulled it from, or you're psychic. Unlimited bonus points if you can say what code has had it's claws on it before execution flow got to this point. In short, steer well clear.
3. Scattered HTML and SQL

Search for some common SQL and HTML strings. You should be able to determine very quickly whether these are appropriate places for HTML or SQL. If you find HTML and SQL in the same file, "crappyness" is most definitely confirmed.
4. Classes do too much

Find the 3 largest class files by bit size. Take a look at the class name. Does it indicate a distinct responsibility? Look at the methods. Are the tasks they perform closely related? If not, run away screaming.
5. Lots of properties are public or lots of properties are static

If lots of properties are declared "public static", triple your quote. If I have to explain why, maybe there's an open position on the development team of the software for you.
6. Multiple levels of inheritance

More than 2 levels inheritance should be avoided like the plague. I stake my life on the resulting objects having too much unrelated behaviour (ok, maybe not my life, but if you find a proper use of more than 2 levels of inheritance, I'll buy you a beer).
7. The authors try to use Design Patterns

Whether or not the authors have a clue is easily determined by searching for some of the most common design patters. Search the code base and/or documentation for "factory", "decorator", "strategy" etc. If present, you can pretty quickly determine whether the authors know their stuff or are trying to look interesting. That is, if you know how the code should look. If not, refuse to take the project until you do.
8. The software messes with the error level

Well written applications run fine at any error level. Searching the files for /error_level\(.*\)/ should do the trick. In case of hits, try replacing the value with E_STRICT. That's little more than a formality though.
9. In the code base, there is a directory called "core"

This is usually used as an excuse to have the whole application dependent on whatever is in there. Despite the appeal of the term (it does make the contents sound pretty cool and important), defining a "core" is a sign of bad design.
10. The software uses it's own template language.

Be afraid. Very afraid. These guys are definitely in the business of reinventing the wheel. Ignore this warning and you will find yourself spending the better part of a day simulating a "for" loop.



Thursday, June 18, 2009

SSH Auto-mount Network Share

(Beware - This blog/tutorial is directed towards linux based users)
When doing any type of work, especially web work, one of the royal pains is FTPing to your server, or any type of file transfer. Well now you can make it quick and painless. Let me introduce SSHFS. There are 3 major components when creating the SSHFS, and I will guide you through creating and installing all of the necessary steps. Now you can mount and use your file system to automatically upload files and folders to your server with ease.

The 3 Major components:

  1. SSH Automatic Login
  2. Install SSHFS
  3. Mount your folder(s)

SSH Automatic Login

Run this command (with the obvious variable substitutions). It should create a public ssh key on your server.

ssh-copy-id [-i [identity_file]] [user@]machine
  1. ssh-keygen -t dsa
  2. ssh-copy-id user@machiner.

Check to make sure it's there, the file should be called, "authorized_keys".

ls -al ~/.ssh/

If you're having trouble with this part, you can reference this tutorial which breaks this component into smaller steps: SSH Automatic Login.

Install SSHFS

sudo apt-get install sshfs

Or use whatever package manager your distribution provides.

Mount

Create a shell script, we'll call it "mount.sh", and add the contents:

sshfs [user]@[your_server].com:/dir/on/server /dir/to/mount

Run the script:

./mount.sh

Go to the mounted directory and run the 'ls' command to make sure all of your files/folders from your server show up in your local directory.

After you have this successfully working you should at it to your startup scripts.

System >> Preferences >> Sessions >> [add_a_new_entry]

You should be all set. You should have an automatic SSH login (no prompt for a password) from your computer to your server and a mounted folder to your server that acts as an automatic FTP client. The files in your mounted directory should be synced with that of your server. Now all you have to do is move or copy your desired files/folders into the mounted directory, and voila, they're on your server.


Thursday, January 29, 2009

Dynamic Image Generation

Long and boring back-story....

One of the standard features of a message board is allowing members to have a signature, which is appended to the bottom of each post they make. Posters can put whatever they want into the signature (within forum settings). Putting quotes in one's signature is one of the more popular things to do.

A lot of people put in some motto they live by, some funny quote by some famous person, whatever. Some people like to quote things other posters on the board have said. I am one of those people. I think it's fun and promotes a sense of belonging to the community.

I've been a member of the phpfreaks forum for a number of years now, and over the years, I have posted and come across quotes that were (to me, anyways) worth collecting. But having a bunch of quotes in a sig isn't very convenient.

Click Here to Read Full Article from www.phpfreaks.com

Tuesday, January 27, 2009

MySQL University

MySQL University is a series of free web seminars. Each week (on Thursdays) you have a unique opportunity to learn something interesting from MySQL developers and professionals.

MySQL University sessions cover wide range of topics including server administration, extending MySQL functionality, or just tips for better performance of your queries.

The sessions are conducted using DimDim, a web based conference tool build in Flash. It works really good even if your connection is not the fastest one.
During the session, the presenter will show slides and talk about the topic (so it's pretty important that you can understand spoken English), and you and other participants can ask questions using built in chat.
I strongly recommend you to take part in 'live' sessions as it is pretty unique experience, but if for some reason you can't, then there is archive of past sessions, often with flash recording, available at MySQL University's home page.
On the same page you will also find more detailed information on participation, as well as a schedule of upcoming sessions with abstracts and presentation slides, to help you decide if particular subject will be interesting to you or not.

There's also a Google Calendar with MySQL University Schedule available, to which you can subscribe.

From now on, I will (if time permits) post here on PHPfreaks about upcoming sessions that might be interesting for an 'average' PHP developer.

The one that takes place next Thursday is titled 'Scalability Challenges in an InnoDB-based Replication Environment' and seems to be directed more to server administrators. If however, you run your website on a VPS or a dedicated server, you might as well take a look at it.

Have fun!

Thursday, January 22, 2009

Where can I learn about PHP and MySQL ?

The official PHP site is http://www.php.net and the online documentation is found at http://www.php.net/manual

If you would rather follow a tutorial, then check out http://www.devshed.com (this covers PHP and others) or http://www.phpbuilder.com or just do a search on google for PHP Tutorials.

Especially look into how PHP integrates with MySQL so you can program database powered websites. If you are the type of person who likes to dive in the deepend, try downloading some basic scripts from http://www.hotscripts.com and/or http://php.resourceindex.com and start ripping apart the code to see what's being done.

The official MySQL site , is www.mysql.org, also look into a great mysql tutorial at

http://dev.mysql.com/doc/refman/5.0/en/tutorial.html

lastly below is a link to a dozen php and mysql tutorials frm webreference.com http://www.webreference.com/programming/php/

php mysql training cources at Kolkata, India