473,785 Members | 2,468 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

chain methods, is it possible to break a chain?

88 New Member
Dear sir,

say, do you know if it is possible to "break" a method chain in php?

e.g.

Expand|Select|Wrap|Line Numbers
  1.  
  2. class a{
  3.  
  4. function x(){
  5.   return $this;
  6. }
  7.  
  8. function y(){
  9.   if(condition===true){
  10.     return $this;
  11.   }
  12.   else{
  13.     return false;
  14.   }
  15. }
  16.  
  17. function z(){
  18.   ...
  19. }
  20.  
  21. $a=new a;
  22.  
  23. $this->x()->y()->z();
  24.  
  25. }
  26.  
  27.  
In the current example if the "condition" in method "y" is false an error will be thrown after y is evaluated, because z() can not be accessed from a non-object (that is "false" which is returned instead of "$this").

What I am trying to do dear sir, is to break the chain at juncture "y", that is,

when y returns false, then z should not be evaluated,

do you my good man know how I can achieve this?

Grateful for answer,

yours sincerely
Sep 9 '09 #1
11 6004
Markus
6,050 Recognized Expert Expert
You could throw an exception instead of returning false, and then run your obj calls in a try/catch block.
Sep 9 '09 #2
ManWithNoName
88 New Member
Hi again!

Thanks for your reply, and your tips for an approach to this problem,

I'll look into this :D
Sep 9 '09 #3
Markus
6,050 Recognized Expert Expert
@ManWithNoName
No problamo! Let us know how you get on.

Mark.
Sep 10 '09 #4
ManWithNoName
88 New Member
I never used exceptions, but I can’t see how the basic set up could be used for my problem.

e.g. (in class a)
Expand|Select|Wrap|Line Numbers
  1. public function y(){
  2.   if(condition===true){
  3.     return $this;
  4.   }
  5.   else{
  6.     throw new Exception("false");
  7.   }
  8. }
  9.  
But this still means z() needs to be evaluated… (i.e. the chain won’t “break” at x() and return and thus never invoking z())

I have thought about this, and I don’t think this is possible to do what I want to do… PHP will evaluate the entire chain and expects that the methods are being called from a proper class object where the current called method exists…
Sep 11 '09 #5
Markus
6,050 Recognized Expert Expert
Uh, confused. The code below produces the expected result, that is, the chaining breaks when an exception is thrown:

Expand|Select|Wrap|Line Numbers
  1. <?php
  2.  
  3.     class TestChain { 
  4.  
  5.         public function x() {
  6.             printf("Method %s called\n", __METHOD__);
  7.  
  8.             return $this;
  9.         }
  10.  
  11.         public function y($throw = TRUE) {
  12.             printf("Method %s called\n", __METHOD__);
  13.  
  14.             if($throw) throw new Exception('Breaking');
  15.             else return $this;
  16.         }
  17.  
  18.         public function z() {
  19.             printf("Method %s called\n", __METHOD__);
  20.  
  21.             return $this;
  22.         }
  23.  
  24.     }
  25.  
  26.     $tc = new TestChain;
  27.  
  28.     try {
  29.         // Should eventually evaluate z()
  30.         $tc->x()->y(FALSE)->z();
  31.         print "Method chaing ran well.\n";
  32.     } catch (Exception $e) {
  33.         printf("Method chaining failed: %s\n", $e->getMessage());
  34.     }
  35.  
  36.     try {
  37.         // Should not evaluate z()
  38.         $tc->x()->y(TRUE)->z();
  39.         print "Method chaing ran well.\n";
  40.     } catch (Exception $e) {
  41.         printf("Method chaining failed: %s\n", $e->getMessage());
  42.     }
  43.  
Although, I'm unable to make heads or tails on whether this is what you want or not.

Mark.
Sep 11 '09 #6
ManWithNoName
88 New Member
Thanks Markus but the problem lies in the “wrapping”, I don’t want to wrap the “chain” with try/catch,

I would like to have all necessary functionality embedded in the methods, in order to have a more “clean” and convenient code ;)

e.g.

Expand|Select|Wrap|Line Numbers
  1. $return=$this->database()->connect()->select_row();
  2. $this->another_method_not_related_to_the_previous_method()->does_something_else(); 
  3.  
The objective is: If connect() fails, return false, then $return will contain “false” and select_row() should never be evaluated,

the problem is that if connect() returns false, then select_row() will throw an error about not being able to init from a non object,

and if connect() returns $this, I have to evaluate a method that does not need to be initiated, and if connect() was false, how would select_row() know this? I would need to pass a variable between them, and that is not pretty :(

EDIT
I just found an example of passing a variable between methods in order to track "false", http://www.hawkhost.com/blog/2009/06...thod-chaining/, I do not like this implementation, but I can't see any other way of doing this...
Sep 11 '09 #7
Markus
6,050 Recognized Expert Expert
@ManWithNoName
Somethings just aren't built into a language, and this isn't into PHP.

@hack: ick! I prefer my elegant try/catch. ;)
Sep 11 '09 #8
ManWithNoName
88 New Member
Thanks for trying to help me though.
Sep 12 '09 #9
shulace717
9 New Member
This is an older post, but I'm new to PHP (about a month into it) and found this interresting. After some research I think I've found a more direct solution.

Although, this can be applied with one line of code and absolutely no alterations to the class or methods, there is a catch. This evaluates the method chain twice.

The first time it is evaluated a boolean datatype, as the Logicial Operators work down the chain searching for a not TRUE value.

Basically, here is my 1 line solution:
($class->Ax() && $class ->Ay() && $class->Az()) ? ($result = $class->Ax()->Ay()->Az()) : ($result = FALSE);


Logical Operators
Expand|Select|Wrap|Line Numbers
  1. ($class->Ax() && $class ->Ay() && $class->Az())
Ternary Operator - if
Expand|Select|Wrap|Line Numbers
  1. ?
returned value of Method Chain (if TRUE)
Expand|Select|Wrap|Line Numbers
  1. ($result = $class->Ax()->Ay()->Az()) 
Ternary Operator - then
Expand|Select|Wrap|Line Numbers
  1. :
validate FALSE boolean for a break in the chain.
Expand|Select|Wrap|Line Numbers
  1. ($result = FALSE);
It's not perfect. You can follow the $trace global below to see how it travels the chain twice. However, I think it's effective and a step in the right direction.

Here's a bunch of code, consisting of a basic class and multiple test outputs at the bottom.

Please let me know what you think and how this could be further improved!

Expand|Select|Wrap|Line Numbers
  1. <?PHP
  2. $trace ='';
  3. $result = '';
  4.  
  5. class Main
  6.  
  7.     public $condition_A = TRUE;
  8.     public $condition_B = TRUE;
  9.  
  10.     function Ax(){ 
  11.         $GLOBALS['trace'] .= " --> ". __METHOD__;
  12.         return $this; 
  13.     } 
  14.     function Ay(){ 
  15.         if($this->condition_A===TRUE){ 
  16.         $GLOBALS['trace'] .= " --> ". __METHOD__;
  17.             return $this; 
  18.         } 
  19.         else{return FALSE;} 
  20.     } 
  21.     function Az(){ 
  22.         $GLOBALS['trace'] .= " --> ". __METHOD__;
  23.         return "Your requested row data"; 
  24.     } 
  25.       function Bx(){ 
  26.         $GLOBALS['trace'] .= " --> ". __METHOD__;
  27.         return $this; 
  28.     }
  29.     function By(){ 
  30.         if($this->condition_B===TRUE){ 
  31.             $GLOBALS['trace'] .= " --> ". __METHOD__;
  32.             return $this; 
  33.         } 
  34.         else{
  35.             $GLOBALS['trace'] .= " --> ". __METHOD__;
  36.             return FALSE;
  37.         } 
  38.     } 
  39.     function Bz(){ 
  40.         $GLOBALS['trace'] .= " --> ". __METHOD__;
  41.         return "Your requested row data"; 
  42.     } 
  43.     public function Control(){
  44.         $return = $this->Ax()->Ay()->Az();
  45.         return $return;
  46.     }
  47.  
  48. }
  49.  
  50. $class = new Main;
  51.  
  52. $result = $class->Control();
  53. echo $trace;                    //Output: --> Main::Ax --> Main::Ay --> Main::Az
  54. echo '<br />';
  55. printf (var_dump($result));        //Output: string(23) "Your requested row data" 
  56. echo '<br />';
  57. $trace = $result = NULL;
  58.  
  59. $result = $class->Bx()->By()->Bz();
  60. echo $trace;                    //Output: --> Main::Bx --> Main::By --> Main::Bz
  61. echo '<br />';
  62. printf (var_dump($result));        //Output: string(23) "Your requested row data" 
  63. echo '<br />';
  64. $trace = $result = NULL;
  65.  
  66. $result = $class->Bx() && $class ->By() && $class->Bz();
  67. echo $trace;                    //Output: --> Main::Bx --> Main::By --> Main::Bz
  68. echo '<br />';
  69. printf (var_dump($result));        //Output: string(23) "Your requested row data" 
  70. echo '<br />';
  71. $trace = $result = NULL;
  72.  
  73. $class->condition_B = FALSE;    // <-----  BREAK IN THE CHAIN  --------
  74.  
  75. $result = $class->Bx() && $class ->By() && $class->Bz();
  76. echo $trace;                    //Output: --> Main::Bx --> Main::By
  77. echo '<br />';
  78. printf (var_dump($result));
  79. echo '<br />';                    //Output: bool(false) 
  80. $trace = $result = NULL;
  81.  
  82. $result = $class->Control();
  83. echo $trace;                    //Output: --> Main::Ax --> Main::Ay --> Main::Az
  84. echo '<br />';
  85. printf (var_dump($result));        //Output: string(23) "Your requested row data" 
  86. echo '<br />';
  87. $trace = $result = NULL;
  88. /*
  89. $result = $class->Bx()->By()->Bz();    //Output: Fatal error: Call to a member function Bz() on a non-object in
  90. echo $trace;                     
  91. echo '<br />';
  92. printf (var_dump($result));
  93. echo '<br />';            
  94. */
  95.  
  96. ($class->Ax() && $class ->Ay() && $class->Az()) ? ($result = $class->Ax()->Ay()->Az()) : ($result = FALSE);
  97. echo $trace;                    //Output: --> Main::Ax --> Main::Ay --> Main::Az --> Main::Ax --> Main::Ay --> Main::Az
  98. echo '<br />';
  99. printf (var_dump($result));        //Output: string(23) "Your requested row data" 
  100. echo '<br />';
  101. $trace = $result = NULL;
  102.  
  103. ($class->Bx() && $class ->By() && $class->Bz()) ? ($result = $class->Bx()->By()->Bz()) : ($result = FALSE);
  104. echo $trace;                    //Output: Main::Bx --> Main::By
  105. echo '<br />';
  106. printf (var_dump($result));        //Output: bool(false) 
  107. echo '<br />';
  108. ?>
Jan 29 '10 #10

Sign in to post your reply or Sign up for a free account.

Similar topics

99
5925
by: David MacQuigg | last post by:
I'm not getting any feedback on the most important benefit in my proposed "Ideas for Python 3" thread - the unification of methods and functions. Perhaps it was buried among too many other less important changes, so in this thread I would like to focus on that issue alone. I have edited the Proposed Syntax example below to take out the changes unecessary to this discussion. I left in the change of "instance variable" syntax (...
0
2352
by: Anthony Baxter | last post by:
To go along with the 2.4a3 release, here's an updated version of the decorator PEP. It describes the state of decorators as they are in 2.4a3. PEP: 318 Title: Decorators for Functions and Methods Version: $Revision: 1.34 $ Last-Modified: $Date: 2004/09/03 09:32:50 $ Author: Kevin D. Smith, Jim Jewett, Skip Montanaro, Anthony Baxter
2
1978
by: dcipher | last post by:
I'm in the process of rewritting my graphics library to be purely OO using C++. The following is a section of my heirarchy of classes: PImage // defines all basic graphics routines as virtual functions PImage8 // implements those routines for 8bpp PImage15 // and for 15bpp PImage16 // and 16bpp PImage24 // and so on...
1
2419
by: Jeff Smith | last post by:
Can I load custom web user controls dynamically and access the properties and methods without having to explicitly define custom control types (example 2 below). I have custom web control named EditStuff.ascx which reads from an xml file and loads controls to its self based on string value in xml nodes collection of the xml. There are several controls that can be loaded and for each one there exists a public method called 'IntiControl'...
10
105202
by: r035198x | last post by:
The Object class has five non final methods namely equals, hashCode, toString, clone, and finalize. These were designed to be overridden according to specific general contracts. Other classes that make use of these methods assume that the methods obey these contracts so it is necessary to ensure that if your classes override these methods, they do so correctly. In this article I'll take a look at the equals and hashCode methods. ...
318
11138
by: King Raz | last post by:
The shootout site has benchmarks comparing different languages. It includes C# Mono vs Java but not C# .NET vs Java. So I went through all the benchmark on the site ... http://kingrazi.blogspot.com/2008/05/shootout-c-net-vs-java-benchmarks.html Just to keep the post on topic for my friends at comp.lang.c++, how do I play default windows sounds with C++?
2
1774
by: DanYan | last post by:
So I was doing some stuff in Javascript, and I want to get access to a function's scope chain. As a simplified example of what I actually am trying to do, suppose I have this: function add(b) { return function(a) { return a + b; }; }
15
3238
by: jzakiya | last post by:
I'm translating a program in Python that has this IF Then chain IF x1 < limit: --- do a --- IF x2 < limit: --- do b --- IF x3 < limit: --- do c --- .----- ------ IF x10 < limt: --- do j --- THEN
6
1454
by: vwkng1987 | last post by:
Hi everyone Please look at the code below: (I am picking up JS from Crockfold and a few other online sources too) *************************************************************** function Employee(name){ this.name = name || 'default'; } function WorkerBee(name, dept){
0
9647
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
1
10101
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
8988
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
7509
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6744
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5528
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4063
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
3665
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2893
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.