Welcome to our forums...

If this is your first visit, be sure to check out the FAQ by clicking the link above. You may have to register before you can post: click the register link above to proceed.

Forum Statistics

  • Forum Members:
  • Total Threads:
  • Total Posts: 9
There are 1 users currently browsing forums.
PHP Articles Read and post PHP tutorials.

Reply
  #1  
Old 09-17-2006
Mau Mau is offline
A friend
 
Join Date: Jun 2005
Location: California, USA
Age: 20
Posts: 2,956
Rep Power: 8
Mau is on a distinguished road
Ticks - The PHP Construct You've Never Used

Click here to tell your friends about ticks!

You've probably never used it, never saw it, or never found a practical use for ticks, a underused and powerful feature of PHP that allows you to implement exceptions in PHP4, do intensive debugging and profiling, check database connections, turn PHP into an event driven language, or harness complex control over your code.

Concept of Ticks
From the PHP manual: "A tick is an event that occurs for every N low-level statements executed by the parser within the declare block." So, for example, if N=1, then after every statement, the tick event will be executed. Here's an example:
PHP Code:
// N = 1
$pass md5('qwerty'); /* Tick executed */
$pass strrev($pass);  /* Tick executed */
echo $pass;  /* Tick executed */ 
PHP Code:
// N = 2
$pass md5('qwerty'); 
$pass strrev($pass); /* Tick executed */
echo $pass
PHP Code:
// N = 3
$pass md5('qwerty');
$pass strrev($pass);
echo 
$pass;  /* Tick executed */ 
The above code is showing 3 examples. In the first one, N = 1, which means that our tick will be executed after every statement. As we increase N, our tick is executed less and less.

Enabling Ticks
So, how do you use ticks? The above code does not have ticks enabled. To enable them, you use the exclusive declare construct. Declare is a construct for the parser to inject code after the specified "ticks" constant. The syntax for declare is:
PHP Code:
declare (ticks=1)
{
     
// Code Here

So, to make our above example complete:
PHP Code:
declare (ticks=1)
{
     
$pass md5('qwerty'); /* Tick executed */
     
$pass strrev($pass);  /* Tick executed */
     
echo $pass;  /* Tick executed */
}

declare (
ticks=2)
{
     
$pass md5('qwerty'); 
     
$pass strrev($pass); /* Tick executed */
     
echo $pass
}

declare (
ticks 3)
{
     
$pass md5('qwerty');
     
$pass strrev($pass);
     echo 
$pass;  /* Tick executed */

We've now enabled ticks for our code. But, it's still useless. As it is right now, nothing is executed in the tick event. Let's define something.

Implementing a Tick
We can define a single function or method to be called using the register_tick_function() function. This specifies the event.

So, all together now:
PHP Code:
declare (ticks=1)
{
     
// Code Here

So, to make our above example complete:
PHP Code:
function profile_memory()
{
     echo 
'<!--' memory_get_usage() . '-->';
}

register_tick_function('profile_memory');
declare (
ticks=1)
{
     
$pass md5('qwerty'); /* Tick executed */
     
$pass strrev($pass);  /* Tick executed */
     
echo $pass;  /* Tick executed */
}

register_tick_function('profile_memory');
declare (
ticks=2)
{
     
$pass md5('qwerty'); 
     
$pass strrev($pass); /* Tick executed */
     
echo $pass
}

register_tick_function('profile_memory');
declare (
ticks 3)
{
     
$pass md5('qwerty');
     
$pass strrev($pass);
     echo 
$pass;  /* Tick executed */

The above code shows us how we can monitor memory usage and easily locate the memory intensive parts. We can watch where it creeps up and find ways to cut back on our memory usage. Pretty cool, eh? It sure beats manually putting in profile_memory() every so lines. We can easily disable this by removing our call to register_tick_function.

This totally useless!
Not so. I have found quite a few uses for this:
  • Writing something that checks to see if the database connection has been dropped. If so, throw an exception or handle it somehow.
  • Implement exceptions in PHP4. To do this, you would have a throw() function and a tick function that would check the value of the throw function.
  • Monitor memory usage and script executation time. You can easily find the slow parts using ticks.
  • Do complex buffering on your code.
  • Turn PHP into an event driven programming language. No more exception hacks.

Ticks let you dynamically segment your code. Instead of debugging a PHP file, you can now debug PHP line numbers. You can also use ticks outside of debugging, such as turning PHP into an event driven language. Your tick function could check the value of a variable and call a function once the value has changed.

Put it in the Global Scope
You can have ticks work globally by putting this at the top of your script:
PHP Code:
declare(ticks=1); 
Do they work in loops?
Yes, they work in loops and will be executed in the iteration of the loops. If ticks=1 and the register_tick_function is profile(), your parser is really writing something like this:
PHP Code:
for ($x 0$x 990$x++)
{
    echo 
'Test'profile();
    echo 
'Testing'profile();

At first glance, profile() is only being called twice. In reality, it's being called 2*999 times. This is where the true power of ticks come in.

Apache and Windows - Bad Match
Avoid using this on Apache with Windows -- there have been reports of system crashes.

Last edited by Mau; 09-20-2006 at 10:33 PM.
Reply With Quote
  #2  
Old 09-17-2006
Forum Administrator
 
Join Date: Mar 2006
Location: Toronto, Ontario
Posts: 2,396
Rep Power: 7
Nick Presta is on a distinguished road
Re: Ticks - The PHP Construct You've Never Used

Wow. That is actually pretty neat.

You could totally use this as a trace type thing where your tick logs your memory useage along with the function name so you can see when your script spikes and why.
Reply With Quote
  #3  
Old 09-17-2006
callumjones's Avatar
Powered by an API.
 
Join Date: Mar 2005
Location: Perth, Australia
Age: 20
Posts: 3,613
Rep Power: 10
callumjones has a spectacular aura aboutcallumjones has a spectacular aura about
Re: Ticks - The PHP Construct You've Never Used

Wow, that is quite handy. What sort of gap is the tick run depending on the N value, say if N=4 is it run every 1/4 of lines?
Reply With Quote
  #4  
Old 09-18-2006
Err... Bean, Mister Bean
 
Join Date: Jul 2005
Location: Derbyshire, UK
Age: 18
Posts: 2,320
Rep Power: 8
sirjavabean is on a distinguished road
Re: Ticks - The PHP Construct You've Never Used

Nice!

Why does
PHP Code:
<?php

function foo()
{
    echo(
'foo()<br />');
}

register_tick_function('foo');

declare(
ticks 1)
{
    echo(
'Hello<br />');
}

?>
keep adding more foo()s every time you refresh the page?
Reply With Quote
  #5  
Old 09-18-2006
Mau Mau is offline
A friend
 
Join Date: Jun 2005
Location: California, USA
Age: 20
Posts: 2,956
Rep Power: 8
Mau is on a distinguished road
Re: Ticks - The PHP Construct You've Never Used

Quote:
callumjones originally posted: View Post
Wow, that is quite handy. What sort of gap is the tick run depending on the N value, say if N=4 is it run every 1/4 of lines?
The gap is going to be whatever you specify. So, if N = 4, your tick function will execute every 4 lines.

Quote:
sirjavabean originally posted: View Post
Nice!

Why does
PHP Code:
<?php

function foo()
{
    echo(
'foo()<br />');
}

register_tick_function('foo');

declare(
ticks 1)
{
    echo(
'Hello<br />');
}

?>
keep adding more foo()s every time you refresh the page?
This should only produce 1 tick and echo foo() once. Is it remembering the state between page loads?
Reply With Quote
  #6  
Old 09-22-2006
chrisxkelley's Avatar
A Toddler - Don't be Fooled!
 
Join Date: Jan 2005
Location: Arroyo Grande, California
Age: 21
Posts: 35
Rep Power: 0
chrisxkelley is on a distinguished road
Re: Ticks - The PHP Construct You've Never Used

interesting. any idea why the following runs the function foo() three times:
PHP Code:
#! /usr/bin/php

<?php
function foo()
{
 echo(
'foo()<br />');
}
register_tick_function('foo');
declare(
ticks 1){}

# prints foo()<br />foo()<br />foo()<br />
?>
and also why N=2 or N=3 after that only runs foo() once, yet above N=2 or N=3, foo isnt run at all

PHP Code:
#! /usr/bin/php

<?php
function foo()
{
 echo(
'foo()<br />');
}
register_tick_function('foo');
declare(
ticks 3){} #try N=2-5

# prints foo()<br />
?>

i'll have to play around with this a bit. interesting find. where did you learn about this?
Reply With Quote
  #7  
Old 09-22-2006
Mau Mau is offline
A friend
 
Join Date: Jun 2005
Location: California, USA
Age: 20
Posts: 2,956
Rep Power: 8
Mau is on a distinguished road
Re: Ticks - The PHP Construct You've Never Used

Remember that when you use ticks, they are after each low-level statements, whether they are stated or not. So, my bet is that the parser is adding something to the opcode which counts as a low-level statement.
Reply With Quote
  #8  
Old 09-29-2006
New Born
 
Join Date: Sep 2006
Posts: 1
Rep Power: 0
chugadie is on a distinguished road
Re: Ticks - The PHP Construct You've Never Used

Hmm.. I don't think you can do true exception handling with this technique, but you can come close. I say you can't do true exceptions because you can't interrupt the flow of the declare {} block. (or can you? (break/continue))

PHP Code:



# ERROR HANDLING
$estack ErrorStack::_singleton();
set_error_handler( array( &$estack'_errorHandler') );

register_tick_function(array (&$estack,'watchErrorTicks') );

declare(
ticks=1) {    //try ...
   
ErrorStack::registerCatch'myCatch' );

   echo 
"hello world\n";
}


declare(
ticks=1) {    //try ...
   
ErrorStack::registerCatch'myCatch' );

   
trigger_error("I don't feel like running.");
   
trigger_error("But, I still have to run...");
}



function 
myCatch($e) {
        echo 
"*** DANGER, caught error: ".$e->toString()."\n";


Registering a catch function first allows you to guide errors to a certain function *before* they happen, but the following statements in the declare block still run. You can only continue down the stack with function calls, or die and jump all the way back up to the top. You can't stop can get off at any level of the stack on your way up. You could encapsulate each call in a declare, but that isn't much different than just checking each return value after each call. If you have to work with other libraries that just call trigger_error(), this is a good way to capture and work with those.
Reply With Quote
  #9  
Old 09-29-2006
Mau Mau is offline
A friend
 
Join Date: Jun 2005
Location: California, USA
Age: 20
Posts: 2,956
Rep Power: 8
Mau is on a distinguished road
Re: Ticks - The PHP Construct You've Never Used

That's true -- you cannot get some of the more powerful features of exceptions in PHP4, but you can simulate putting the entire script in a try...catch block. Then, when an exception is "thrown," act upon it, and exit the script if required.
Reply With Quote


Reply


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On


Similar Threads
Thread Thread Starter Forum Replies Last Post
PHP Tutorial for beginners YoungCoder PHP Articles 19 04-23-2006 02:31 PM
What is PHP? wizard PHP Articles 4 11-27-2005 06:38 AM
Php Syntax wizard PHP Articles 1 10-06-2005 01:53 AM
PHP Manual [Chris's Version] Chrishasfun PHP Articles 0 01-02-2005 02:22 PM