PHP - overloading system function, debugging…

January 27th, 2010
No comments
1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)

Today I needed to find a file where is called PHP system function, it was to find the place where the email is send. The problem was that the system is huge and messy. There is no wrapper (PHPMailer or something) which will be sending the emails. You will need to install APD, it’s a PECL extension. After that you can overload the mail function and with debug_backtrace get the stacktrace.


// code of the override function
$code=<<<'CODE'
$trace=debug_backtrace();
$caller=array_shift($trace);
echo 'mail() called by '.$caller['function']
if (isset($caller['class']))
echo 'in '.$caller['class'];
CODE;
//install override
override_function('mail', '$to,$subject,$msg,$hdrs,$params', $code);
Share and Bookmark:
  • Digg
  • del.icio.us
  • Facebook
  • Mixx
  • Google
  • blogmarks
  • DotNetKicks
  • E-mail this story to a friend!
  • Furl
  • Live
  • Reddit
  • Slashdot

PHP

Difference between Clustered and Non-Clustered Index Data Structures

May 28th, 2009
No comments
1 Star2 Stars3 Stars4 Stars5 Stars (1 votes, average: 3.00 out of 5)

When you first create a new table, there is no index created by default. In technical terms, a table without an index is called a “heap”. As you would expect, the data we will insert into the table will be returned in the same order. A non-clustered index is a special type of index in which the logical order of the index does not match the physical stored order of the rows on disk. The leaf node of a non-clustered index does not consist of the data pages. Instead, the leaf nodes contain index rows.

A clustered index is a special type of index that reorders the way records in the table are physically stored. Therefore table can have only one clustered index. The leaf nodes of a clustered index contain the data pages.

Clustered index is good when you know in which order you will be returning the records in most cases. You can create clustered index and after that you don’t need to use ORDER BY statement. This will be much more faster. If the order is not important for you and will not create clustered index by yourself, then primary key will be clustered index by default. There is nothing bad not to have the clustered index, it can speed up inserting rows.

Share and Bookmark:
  • Digg
  • del.icio.us
  • Facebook
  • Mixx
  • Google
  • blogmarks
  • DotNetKicks
  • E-mail this story to a friend!
  • Furl
  • Live
  • Reddit
  • Slashdot

Database

SVN commit basic policy guide

February 19th, 2009
1 comment
1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)

Think twice before committing

Committing something to SVN has serious consequences. All other developers will get your changes once they are in SVN, and if they break something, they will break it for everybody. All commits will be publicly available in the SVN repository forever.

The baseline is: Be aware of the consequences of your commits. Take time to think about them before committing.

Never commit code that doesn’t compile

Compile the code and correct all errors before committing. Make sure that newly added files are comitted. If they are missing your local compile will work fine but everybody else won’t be able to compile.

Run all tests and check they passed.

You certainly should make sure that the code compiles with your local setup and platform. You should also consider what consequences your commit will have for compiling on another architecture. When you made a change to database structure, commit alter scripts as well.

Test your changes before committing

Build the packages and start the application affected by your change and make sure that the changes behaves as desired.
Double check what you commit.

Do a “svn up” and a “svn diff” before committing. Take messages from SVN about conflicts, unknown files, etc. seriously. The “svn diff” will tell you exactly what you will be committing. Check if that’s really what you intended to commit.

Always add descriptive log messages

Log messages should be understandable to someone who sees only the log. They shouldn’t depend on information outside the context of the commit. Try to put the log messages only to those files which are really affected by the change described in the log message.

In particular put all important information which can’t be seen from the diff in the log message.

Don’t add email, skype or any other communication as log message.

Respect special commit policies set by the release plans

Respect the policies of the current release phase, i.e. avoid commiting new features and code shortly before a planed release.

Source control systems are not a substitute for developer communication

When you plan to make changes which affect a lot of different code in SVN, announce them on the mailing list in advance.

Changes which affect a lot of code in SVN, like making use of a new feature in the libs, might break other code even if they look trivial, e.g., because an application must also compile with older versions of the libs for some reasons. By announcing the changes in advance, developers are prepared and can express concerns before something gets broken.

Take responsibility for your commits

If your commit breaks something or has side effects on other code, take the responsibility to fix or help fix the problems.

Don’t commit code you don’t understand

Avoid things like “I don’t know why it crashes, but when I do this, it does not crash anymore.” or “I’m not completely sure if thats right, but at least it works for me.”.

If you don’t find a solution to a problem, discuss it with other developers.

Don’t abuse your SVN account to push in changes with which other developers disagree

If there are disagreements over code changes, these should be resolved by discussing them on the mailing lists or in private, not by forcing code on others by simply committing the changes to SVN.

If you commit bug fixes, consider porting the fixes to other branches

Use the same comment for both the original fix and the back port, that way it is easy to see which fixes have been backported already.

If you fix bugs reported on the bug tracking system, add the bug number to the log message

In order to keep the bug tracking system in sync with SVN, you should reference the bug report in your commits, and close the fixed bugs in the bug tracking system.

This doesn’t mean that you don’t need an understandable log message. It should be clear from the log message what has been changed without looking at the bug report.

For example: “Fixed add to basket button (#1859)”

Don’t add files generated by standard tools to the repository

Files generated at build shouldn’t be checked into the repository because this is redundant information and might cause conflicts. Only real source files should be in SVN.

Don’t use SVN keywords like Id or Log in the source files

These tags cause unnecessary conflicts when merging branches and don’t contain any information which wouldn’t be available in the SVN repository anyway.

Make “atomic” commits

SVN has the ability to commit more than one file at a time. Therefore, please commit all related changes in multiple files, even if they span over multiple directories at the same time in the same commit. This way, you ensure that SVN stays in a compilable state before and after the commit.

Don’t mix formatting changes with code changes

Changing formatting like indenting or white spaces blows up the diff, so that it is hard to find code changes if they are mixed with reinventing commits or similar things when looking at the logs and diffs later. Committing formatting changes separately solves this problem.

Share and Bookmark:
  • Digg
  • del.icio.us
  • Facebook
  • Mixx
  • Google
  • blogmarks
  • DotNetKicks
  • E-mail this story to a friend!
  • Furl
  • Live
  • Reddit
  • Slashdot

Source versioning

Simple custom event handling

February 17th, 2009
1 comment
1 Star2 Stars3 Stars4 Stars5 Stars (1 votes, average: 4.00 out of 5)

The event model in C# is based on idea of publisher and subscribers. Each publisher can have more subscribers subscribed to each event. Publisher will do some logic and publish an event to all subscribers. Subscribers will do their logic reacting to raised event. In C#, any object can publish a set of events to which other applications can subscribe. When the publishing class raises an event, all the subscribed applications are notified. Example of this behaviour can be that the application will subscribe to event which will be raised from database connection control when the connection is lost. Main application will know, that this happened and can react on that event –reconnect, show alert message, etc.

Conventions

The following important conventions are used with events:

  • Event Handlers in the .NET Framework return void and take two parameters.
  • The first paramter is the source of the event; that is the publishing object.
  • The second parameter is an object derived from EventArgs.
  • Events are properties of the class publishing the event.
  • The keyword event controls how the event property is accessed by the subscribing classes.

Example

Lets say that we have Product class which has Name property. When the name is changed we want ot change this name in Label as well. We don’t know from where this name can be changed. We will “convert” product class into event publisher and the window where is the label will subscribe to this event.

First step will be to create the event and method which will fire this event.


public class Product
{
  public string Name { get; set; }

  // Delegate
  public delegate void PropertyChangeHandler (object sender,  EventArgs data);

  // The event
  public event PropertyChangeHandler PropertyChange; 

  // The method which fires the Event
  protected void OnPropertyChange (object sender,  EventArgs data)
  {
    // Check if there are any Subscribers
    if (PropertyChange!= null)
    {
      // Call the Event
      PropertyChange (this, data);
    }
  }
}

We created delegate which encapsulates any method that takes these attributes, this delegate must be implemented by all subscribers. Now we need one small change to the class. That will be to fire the event, when Name property is changed. It can be nice to pass information about this change to subscribers with what have been changed and to have old value and new value. For this we will create PropertyChangeEventArgs class which will be derived from EventArgs.


public class PropertyChangeEventArgs : EventArgs
{
  public string PropertyName { get; internal set; }
  public object OldValue { get; internal set; }
  public object NewValue { get; internal set; }

  public PropertyChangeEventArgs(string propertyName, object oldValue, object newValue)
  {
    this.PropertyName = propertyName;
    this.OldValue = oldValue;
    this.NewValue = newValue;
  }
}

public class Product
{
  private string name;
  public string Name {
    get
    {
      This.name;
    }
    Set
    {
      Object old = this.name;
      This.name = value;
      OnPropertyChange(this, new PropertyChangeEventArgs(“Name”, old, value));
    }
  }

  // Delegate
  public delegate void PropertyChangeHandler (object sender,  PropertyChangeEventArgs data);

  // The event
  public event PropertyChangeHandler PropertyChange;

  // The method which fires the Event
  protected void OnPropertyChange (object sender,  PropertyChangeEventArgs data)
  {
    // Check if there are any Subscribers
    if (PropertyChange!= null)
    {
      // Call the Event
      PropertyChange (this, data);
    }
  }
}

Now we are done with the Product class (publisher) and can subscribe to the OnPropertyChange event.


protected void Page_Init(object sender, EventArgs e)
{
  This.Product = new Product();
  This.Product. OnPropertyChange += Product.PropertyChangeHandler(PropertyHasChanged);
}

protected void Page_Load (object sender, EventArgs e)
{
  This.Product.Name = “New name”;
}

public void PropertyHasChanged (object sender,  PropertyChangeEventArgs data)
{
  if(data.PropertyName == “Name”)
  {
    This.ProductLabel.Text = (string)data.NewValue + ‘ was ‘ + (string)data.OldValue;
  }
}

In the Init event we created product instance and subscribe to OnPropertyChange event of Product class. In Load phase we changed name of that product. This operation fired PropertyChange and this was send to all subscribers. This calls PropertyHasChanged method with all informations.

Share and Bookmark:
  • Digg
  • del.icio.us
  • Facebook
  • Mixx
  • Google
  • blogmarks
  • DotNetKicks
  • E-mail this story to a friend!
  • Furl
  • Live
  • Reddit
  • Slashdot

C# , ,

Google Analytics - tracking external links

February 4th, 2009
2 comments
1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)

Recently I was asked to implement extension which will track external links into Google Analytics. For me I was facing to problems. One I that if you have running 3rd party system it’s hard to implement anything, that will change all external links and the second one is that Javascript is not my cup of tea.

I found and implemented one solution which looks simple and works. Main idea is to listen to click on page and if the clicked element is anchor, call Googles page tracking before browser goes to that page. Another solution is to use jQuery, I’ll show this solution later.

First step is to create a listener, what will listen events on page and call another function to handle the action.


function addListener(element, type, functionName)
{
  if(window.addEventListener) {
    element.addEventListener(type, functionName, false);
  }
  else if(window.attachEvent) {
    element.attachEvent('on' + type, functionName);
  }
  else return false;
  return true;
}

addListener(document, 'click', trackingExternalClick);

Second step will be to create function, which will contain the logic for onclick action. Lets say that we want to track anchors which point to external page (starting with http:// or https://) and wants to know whats the clicked domain, we don’t need to know whole url. Name of the function will be trackingExternalClick (third parameter in addListener).


function trackingExternalClick(event) {
  var cElem = (window.event) ? event.srcElement : event.target; //Get the clicked element
  //If it is an Anchor
  if(cElem.nodeName == 'A'){
    // Check if link is external, not contain local domain
    if(cElem.href.indexOf(location.host) == -1) {
    //Replace characters not supported by Google Analytics
      var url = cElem.href.match(/^([http|https]*):\/\/?([^\/]+)/g, "").toString().replace(new RegExp(/^([http|https]*)?:\/\//i),"");
      var str = '/outgoinglink/' + url;
      try{
        pageTracker._trackPageview(str);
      }
      catch(err){ }
    }
  }
}

Same practice can be used to track download links (.zip, .pdf, etc.). We will only change lines 6 to 9.


if(cElem.href.indexOf(".pdf") == -1) {
  //Replace characters not supported by Google Analytics
  var url = cElem.href;
  var str = '/download/' + url;

When you will have problems that these clicks are not tracked, try to move Google Analytics code to the head section of the page and these codes after GA. If you need anything more or wants to help with something, leave a message here.

Share and Bookmark:
  • Digg
  • del.icio.us
  • Facebook
  • Mixx
  • Google
  • blogmarks
  • DotNetKicks
  • E-mail this story to a friend!
  • Furl
  • Live
  • Reddit
  • Slashdot

google , ,