Re: [PHP-DEV] Object comparison
On Fri, Nov 9, 2012 at 2:00 PM, jpauli jpa...@php.net wrote: On Fri, Nov 9, 2012 at 2:18 PM, Christian Stoller stol...@leonex.de wrote: I would like to place a suggestion for comparing objects (I hope it is no problem, because this does not have anything to do with Sara's question - but it came to my mind when I read her mail). It would be a great feature if objects could be compared to other objects with , and the other operators, like it is suggested in RFC https://wiki.php.net/rfc/comparable The DateTime class offers this feature - it would be nice if this could be made usable for userland classes/objects, too. I really like that idea, and the patch looks pretty good and looks backward compatible. I'm +1 with it I'm also +1 with patching the doc to describe the full default compare behavior. Another spot in the docs I would enjoy discussion about ,,=,= comparing two objects: http://php.net/manual/en/language.oop5.object-comparison.php I notice this behavior is suggested in a comment for use in an array_uintersect callback: http://php.tonnikala.org/manual/el/function.array-uintersect.php#72841 Indeed, trying to intersect two arrays of objects with a user callback 'works' with the comparison operator, but maybe this is just luck, or subject to BC break later? ?php class myclass { function __construct($name) { $this-name = $name; } } $o1 = new myclass('o1'); $o2 = new myclass('o2'); $o3 = new myclass('o3'); $o4 = new myclass('o4'); $a1 = array($o1, $o2, $o3); $a2 = array($o3, $o2, $o4); var_dump(array_uintersect($a1, $a2, function($v1, $v2) { if($v1 === $v2) return 0; if($v1 $v2) return 1; return -1; })); I'd expect the comparison there to be roughly equivalent to if(spl_object_hash($v1) spl_object_hash($v2)), no? Info on the default behavior here would be nice. -nathan
Re: [PHP-DEV] Revisit: zend_call_method() - n number of arguments
On Sun, Oct 23, 2011 at 12:50 AM, Stas Malyshev smalys...@sugarcrm.comwrote: Hi! On 10/22/11 2:36 AM, Nathan Nobbe wrote: Hi, Another old issue I'd like to rehash with the upcoming release around the corner [1]. I patched 5.4 alpha2 for review [2]. I think better idea would be to add another API function (zend_call_method_ex?), that implements arbitrary argument count (either via array or via varargs) and make zend_call_method be a case of it, maybe. This way you don't have to break existing API and also don't have to stop at 4. Hi Stas, That's what this patch does, there is a new function zend_call_method_multi, which takes an array, and I've revised zend_call method to use it. I could change it to varargs if that is preferred. thanks, -nathan
[PHP-DEV] Revisit: Traits requiring composing class to implement interface
Hi folks, With a 5.4 release right around the corner I'd like a moment of your time to reconsider this issue [1]. I've read through the original conversation [2] and would summarize the points as follows: . several folks see value in the feature . the feature would not be an impedance for people who did not wish to use it . there was only one objection which was largely subdued The common use case of pairing traits with interfaces is the case where the feature adds value. Just curious why it died on the table if several folks saw value in it, including Stephan who I gather is the primary architect of traits. The dispute regarding the feature was the merit of a 'compile time' check vs placing the burden on the developer to ensure all methods in a trait are provided by the class in which it is used. In an earlier conversation about traits Stefan said this: Yes, Traits are meant to be compile-time only, they are not used to introduce typing relationships. Which makes me even more comfortable about the merit of another compile time check. As I argued in the original thread, the feature is merely an embellishment atop the already supported use of the 'abstract' keyword as it pertains to traits. And what if nothing else are features like PPP, abstract, interfaces etc than syntactic sugar? Plus it will save folks some typing :) [1] https://wiki.php.net/rfc/horizontalreuse#requiring_composing_class_to_implement_interface [2] http://marc.info/?l=php-internalsm=129188077704898 thanks, -nathan
[PHP-DEV] Revisit: zend_call_method() - n number of arguments
Hi, Another old issue I'd like to rehash with the upcoming release around the corner [1]. I patched 5.4 alpha2 for review [2]. Seems like the most appropriate time for a patch of this nature is during a major release, per the previous conversation. According to Marcus the patch is reasonable: I explained to him the exact terms under which he can add the function. And his patch actually followed these terms as far as I could see. Would definitely help keep my PureMVC extension a little cleaner, if I ever get around to finishing it :) [1] http://marc.info/?l=php-internalsm=123493017101177w=2 [2] http://pastebin.com/zygKe9Y5 thanks, -nathan
Re: [PHP-DEV] Revisit: Traits requiring composing class to implement interface
On Sat, Oct 22, 2011 at 8:25 AM, Anthony Ferrara ircmax...@gmail.comwrote: Well, I have a few opinions on this that I think are worth sharing: Anthony, thanks for your reply. 1. If this change is made, we no longer would have mixins, but would have regular multiple-inheritance (With all the issues associated with it). Note that I said mixins and not traits. That's because since these were implemented with state (member properties), they are not traits as implemented, but regular mixins. (Yet another gripe, but that's slightly off topic). While this may be scary to many it is in fact the motivation for the feature. Multiple inheritance or some semblance thereof is something user-space folks have been interested in for some time [1]. There is no unanimous interest for it, nor is there unanimous favor for practically anything in PHP, that's what makes it unique IMO, different strokes for different folks. 2. Traits and mixins are supposed to be the symmetric counterpart to interfaces. An interface is a specification without implementation. A trait/mixin is supposed to be implementation without specification. And a class (including abstract) is implementation with specification. So if you allowed type hinting of traits/mixins, wouldn't that just make them nothing more than abstract classes (in that they can't be used directly, but both provide the same info)? True, but doesn't the use of the abstract keyword in a trait already mean they support specification? There may be an academic concept of a trait, but perhaps it has already been massaged for the PHP implementation. There's a much bigger problem though. How would you solve the problem where a class uses a trait that implements an interface, but you don't pull one of the methods through (for example, you exclude it in the use clause)? At first this sounds simple, just enforce it on the class. But that means that the compiler couldn't enforce the interface at definition time of the trait. So then that means that by the trait implementing the interface is actually *forcing* any class that implements it to be compliant and ensure that it implements the interface. So at that point the trait stops being useful for horizontal reuse, but becomes nothing more than a class with the limitations that brings along. Traits/mixins were designed to avoid this problem. So why should we re-introduce it? I'm sorry I'm missing the point here, could you show a brief sample? I think the *forcing* aspect is the point here though, and it is desired. A trait that uses several methods from an interface, say Iterator or another class like SplFileInfo. The trait should be able to say it needs a subset of the methods in that interface or class today, and may at any time in the future rely on any of the full set of methods defined in the interface or class. Again, this functionality is already available in the current implementation via the abstract keyword. It just seems silly to have to maintain a list of methods by hand that could be done with a concise notation instead. And it's even uglier if the trait relies on more than one class interface, imagine code like this: ?php trait IteratorHelper { /* Iterator */ abstract public function current(); abstract public function key(); abstract public function next(); abstract public function rewind(); abstract public function valid(); /* SplFileInfo */ abstract public function getATime(); abstract public function getBasename(); // etc.. } ? The author is wondering, do I bother to key in all the methods from SplFileInfo now in case I ever use one of the methods I haven't in the original implementation, or wait until I do use another method from SplFileInfo and then update the list of abstract methods. And what if I have an abstract method mentioned in the list, but remove calls to it from within the trait and then forget to update the list, is that bad? Also note the ambiguity introduced without comments indicating which foreign class / interface these abstract (required) methods come from. The comments here, and indeed the feature I suggest, would be more expressive to authors because it would be explicit. Imagine encountering the code segment above with the absence of the comments, you would be good to guess which classes / interfaces the trait was intended to be used with. Instead something like: ?php trait IteratorHelper require Iterator, SplFileInfo { //.. } ? is not only more concise, it is more expressive IMO in that it more clearly indicates the author's intent for the use of said trait. It is also more maintainable because there is no need to maintain a list of methods (for which there is no explicit way to describe the interface / class they belong to) when changes are made. There is also value for documentation tools. With the current paradigm of just the abstract keywords using comments as I suggested is not something a documentation tool can pick up, though
Re: [PHP-DEV] Local PHP docs with search facility
On Thu, Jun 2, 2011 at 4:01 PM, Philip Olson phi...@roshambo.org wrote: On Jun 2, 2011, at 2:46 PM, Richard Riley wrote: Hannes Magnusson hannes.magnus...@gmail.com writes: On Thu, Jun 2, 2011 at 21:03, Richard Riley rile...@googlemail.com wrote: Could some kind soul advise me on how to install php docs localy and have the excellent patterns search work based on an sqllite database? https://wiki.php.net/doc/phd/view Please ask any followup questions on the proper mailinglist, php...@lists.php.net for questions about the docs, or php-webmas...@lists.php.net for questions about the website. Yes, please excuse the wrong group. I realised that after posting. But while we're here, pman is another option: $ pear install phpdocs/pman $ pman mysql_connect That'll show the mysql_connect() documentation as a local man page. not to shabby ;) and to Richard's question about search the -K option may be just the ticket. -nathan
Re: [PHP-DEV] Traits expecting interfaces implicitly leads to expensive runtime checks
On Sun, Dec 12, 2010 at 7:25 AM, Jonathan Bond-Caron jbo...@openmv.comwrote: On Sat Dec 11 10:25 AM, Stefan Marr wrote: http://wiki.php.net/rfc/horizontalreuse#requiring_composing_class_to_impleme nt_interface Are there any objections to implementing this? It's not a bad idea, though I haven't found a strong need for it in the way I plan to use traits. Do you intend to use traits as reusable implementations of interfaces? If not, I could see why this feature isn't of interest to you :) It also turns a trait into something more complex 'copy paste' code with requirements/dependencies. I think copy paste is a good way to conceptualize traits, but feel, practically, they're a bit more complex than that w/ conflict resolution, traits composed of traits, and the issue w/ attributes Stefan has brought up. Essentially, there are already rules being added around the copy paste concept. Also, this feature is mostly an extension of the abstract keyword concept in traits, which they already support. -1 on using 'require' (T_REQUIRE token), an option could be 'within' trait IteratorUser within Iterator { function foo() { $next = $this-next(); ... } } class MyIterator implements Iterator { with IteratorUser; } So the 'with/within' tokens would apply to traits. I feel 'expect', 'need', 'require' etc sound better, matter of opinion really, but it sounds like from an internals perspective it's preferred to reuse existing keywords if possible. Overall I feel -1, more use cases around Trait expresses a requirement for the composing class would help, it seems like useful theory... not convinced it's worth the trouble. If you see the value in the abstract keyword in abstract classes or moreover interfaces in general, I'd consider the value of this feature equal. Of course not everyone uses abstract classes or interfaces :D -nathan
Re: [PHP-DEV] Traits and Properties
On Sat, Dec 11, 2010 at 9:47 AM, Stefan Marr p...@stefan-marr.de wrote: Hi: Traits do not provide any special provisioning for handling properties, especially, there is no language solution for handling colliding property names. The current solution/idiom for handling state safely in a trait is to use either abstract set/get methods or an abstract get that returns a reference to the property in the class. However, at the moment it is possible to define properties in a trait: trait Foo { private $a; public $foo; } For the moment, that information is completely ignored, thus: class Bar { use Foo; } property_exists('Bar', 'a') === false Well, and that is a rather inconsistent status-quo. I would like to have that fixed in one or another way. One possibility would be to forbid property definition in a trait altogether. That reduces a bit the possibility to have wrong expectations about properties, however, the dynamic property creation is still possible. Another way would be to merge the properties in the composing class. The question here would be how to treat visibility modifiers: how to merge public and private, should it result in public, or private? And, to discorage users to go this way, should there be a STRICT notice? Options here are a notice whenever a property is defined in a trait, or whenever properties are silently merged. I would prefer they be definable within traits and merged into classes, otherwise traits will not have the chance to be self-contained entities of reusable logic. Also, I think merging them in is consistent with the treatment given to methods as they pertain to traits. As I'm sure you know: ?php class A { use SomeTrait; } trait SomeTrait { public function traitMethod() {} } method_exists('A', 'traitMethod') === true; ? Regarding visibility modifiers, why not carry them over from the trait directly, private in the trait definition results in private in the class definition. Lastly, I'm not sure why you would want to discourage this usage, I would plan on adding properties in traits myself. -nathan
Re: [PHP-DEV] Traits expecting interfaces implicitly leads to expensive runtime checks
On Thu, Dec 9, 2010 at 4:04 PM, Stefan Marr p...@stefan-marr.de wrote: Hi Nathan: On 09 Dec 2010, at 23:42, Nathan Nobbe wrote: What I'm getting at is the scenario when a trait is designed to be used in concert with the class in which it is being used. In this case the trait expects certain functions to be available on the class in which it is used with. If the methods aren't there (or checked for at runtime) a fatal error is raised. A quick example ?php class A { use AHelper; function blah() {} } trait AHelper { function meh() { // hoping we get used w/ instances of A ... return $this-blah() * 5; } } class B { use AHelper; /// waiting for a runtime error if blah() is ever called .. } ? Do you see what I mean? No, do not really see what you are getting at. How is your approach using the instanceof checks (from the first mail) different from changing AHelper to require blah() by stating this requirement using an abstract method definition? For the trait it is not important where that method is implemented, it just has to be in the final composed class. So, why don't you want the following trait? trait AHelper { abstract function blah(); function meh() { // hoping we get used w/ instances of A ... return $this-blah() * 5; } } Ahh, I see how the abstract methods are working in traits now, I didn't catch that from your first post; thanks for showing that to me. You want to avoid the fatal error during runtime, right? Yes, exactly, and the runtime check for expected interface / class / method. Do you prefer dynamic checks over compile time checks? Def not :D, however, I still think this paradigm is lacking. Don't you think it makes more sense if I write a trait that expects a given interface or class to be able to specify said interface/class in it's entirety with just a single identifier rather than listing out all the methods? For example, I think this would be ugly ?php trait IteratorHelper{ abstract public current(); abstract public key(); abstract public next(); abstract public rewind(); abstract public valid(); } ? essentially you're redeclaring the entire interface in the trait, the same would be true of the public interface of an expected class. i think it would be much more elegant to allow a specification on the trait declaration itself, something like ?php trait IteratorHelper expects Iterator { ... } ? -nathan
Re: [PHP-DEV] Traits expecting interfaces implicitly leads to expensive runtime checks
On Fri, Dec 10, 2010 at 10:15 AM, Martin Wernstahl m4r...@gmail.com wrote: First i have to say that I am not a PHP internals developer, but as a user I think it would maybe be better to just let the trait use the implements keyword, and copy that to the classes utilizing the trait? This is actually in the RFC as a rejected proposal http://wiki.php.net/rfc/traits#rejected_features But what I'm talking about is something different. We're not trying to say 'these are the methods implemented in the trait', rather, 'this trait expects a class it is used with to be of a certain type or implement a certain interface' for the trait to do its job. -nathan
Re: [PHP-DEV] Traits expecting interfaces implicitly leads to expensive runtime checks
On Fri, Dec 10, 2010 at 11:04 AM, Chad Fulton chadful...@gmail.com wrote: On Fri, Dec 10, 2010 at 9:29 AM, Nathan Nobbe quickshif...@gmail.com wrote: On Fri, Dec 10, 2010 at 10:15 AM, Martin Wernstahl m4r...@gmail.com wrote: First i have to say that I am not a PHP internals developer, but as a user I think it would maybe be better to just let the trait use the implements keyword, and copy that to the classes utilizing the trait? This is actually in the RFC as a rejected proposal http://wiki.php.net/rfc/traits#rejected_features But what I'm talking about is something different. We're not trying to say 'these are the methods implemented in the trait', rather, 'this trait expects a class it is used with to be of a certain type or implement a certain interface' for the trait to do its job. -nathan Shouldn't the burden be on the programmer to make sure the trait works with the class using it rather than on the compiler? If they try to use a trait that requires methods that don't exist, it will error out anyway, so it won't be difficult to debug. Well I know PHP is a dynamic language but what about all the compile time features that have come along over the years. The abstract keyword for example vs. the PHP4 way of implementing an 'abstract' method which was triggering an error in the default implementation in a base class. One of the main things a lot of PHP programmers I've worked with hate is waiting for code to hit production and encountering a runtime error w/ something that could have been caught at compile time. I know the notion of compile time in a scripting language like PHP is much less removed from that of C++, Java etc, however there is a notion of it there, obviously. Also, I would suggest this feature be optional, so there is no need to use it if you don't like it. But for those of us who would like to defer as much type checking to the compiler as possible so we don't need runtime checks all over our code or prayers that we've tested every line before production, it would certainly be nice. Lastly, you may know that traits will allow PHP programmers to move away from the delegate pattern which is a common workaround to multiple inheritance at this point. However, in speaking with a colleague over the concept I'm proposing yesterday we discovered the delegate model actually does allow you to specify which class/interface the delegate is used w/, it would be sad not to see comparable support in the trait feature which will mostly eliminate the need for the delegate pattern, see my quick example. ?php class MainClass { private $_oDelegate = null; function addDelegate() { $this-_oDelegate = new Delegate($this); } } class Delegate { private function $_oMain = null; /// delegate gets to say what it can be used with via type hinting function __construct(MainClass $oMainClass) { $this-_oMain = $oMainClass; } } ? Imagine how much cleaner this could be w/ traits, yet just as expressive ?php class MainClass { use Delegate; } trait Delegate require MainClass { ... } ? -nathan
Re: [PHP-DEV] Traits expecting interfaces implicitly leads to expensive runtime checks
On Fri, Dec 10, 2010 at 12:55 PM, Matthew Weier O'Phinney weierophin...@php.net wrote: On 2010-12-10, Nathan Nobbe quickshif...@gmail.com wrote: --0016e6dbe7fb8861a1049712ad63 Content-Type: text/plain; charset=UTF-8 On Fri, Dec 10, 2010 at 11:04 AM, Chad Fulton chadful...@gmail.com wrote: On Fri, Dec 10, 2010 at 9:29 AM, Nathan Nobbe quickshif...@gmail.com wrote: On Fri, Dec 10, 2010 at 10:15 AM, Martin Wernstahl m4r...@gmail.com wrote: First i have to say that I am not a PHP internals developer, but as a user I think it would maybe be better to just let the trait use the implements keyword, and copy that to the classes utilizing the trait? This is actually in the RFC as a rejected proposal http://wiki.php.net/rfc/traits#rejected_features But what I'm talking about is something different. We're not trying to say 'these are the methods implemented in the trait', rather, 'this trait expects a class it is used with to be of a certain type or implement a certain interface' for the trait to do its job. -nathan Shouldn't the burden be on the programmer to make sure the trait works with the class using it rather than on the compiler? If they try to use a trait that requires methods that don't exist, it will error out anyway, so it won't be difficult to debug. Well I know PHP is a dynamic language but what about all the compile time features that have come along over the years. The abstract keyword for example vs. the PHP4 way of implementing an 'abstract' method which was triggering an error in the default implementation in a base class. One of the main things a lot of PHP programmers I've worked with hate is waiting for code to hit production and encountering a runtime error w/ something that could have been caught at compile time. I know the notion of compile time in a scripting language like PHP is much less removed from that of C++, Java etc, however there is a notion of it there, obviously. To me, putting this into the language feels like overkill. Unless you're using an opcode cache, the notion of compile time as a differentiation from runtime in PHP has little relevance -- you still only find out when the script executes. *Only* if you hit the line of code at runtime that would destroy your script; often times this doesn't happen until it's too late, and the code has made it to production. And there is a notion of compile time in PHP, I'm not sure what it's referred to by the internals group, but abstract methods and interfaces definitely constitue compile time checks to me. There's already a way to mitigate this as well: write a testing suite for your application, and exercise it often. If you write your tests well (targeting the discrete behaviors of your application), then most likely they'll catch such errors -- allowing you to fix them before you deploy. Right, so you have to do tons of extra work (writing unit tests) which have to actually test every potential line of failure, when this could just simply be caught up front w/o any second guessing whether or not you've covered all cases in your tests. I'm not against unit tests at all, just saying it's much easier to guarantee you're safely using a trait w/ a compile time check rather than deferring the application author to test suite development. -nathan
Re: [PHP-DEV] Traits expecting interfaces implicitly leads to expensive runtime checks
On Fri, Dec 10, 2010 at 12:39 PM, Chad Fulton chadful...@gmail.com wrote: On Fri, Dec 10, 2010 at 10:39 AM, Nathan Nobbe quickshif...@gmail.com wrote: On Fri, Dec 10, 2010 at 11:04 AM, Chad Fulton chadful...@gmail.com wrote: On Fri, Dec 10, 2010 at 9:29 AM, Nathan Nobbe quickshif...@gmail.com wrote: On Fri, Dec 10, 2010 at 10:15 AM, Martin Wernstahl m4r...@gmail.com wrote: First i have to say that I am not a PHP internals developer, but as a user I think it would maybe be better to just let the trait use the implements keyword, and copy that to the classes utilizing the trait? This is actually in the RFC as a rejected proposal http://wiki.php.net/rfc/traits#rejected_features But what I'm talking about is something different. We're not trying to say 'these are the methods implemented in the trait', rather, 'this trait expects a class it is used with to be of a certain type or implement a certain interface' for the trait to do its job. -nathan Shouldn't the burden be on the programmer to make sure the trait works with the class using it rather than on the compiler? If they try to use a trait that requires methods that don't exist, it will error out anyway, so it won't be difficult to debug. Well I know PHP is a dynamic language but what about all the compile time features that have come along over the years. The abstract keyword for example vs. the PHP4 way of implementing an 'abstract' method which was triggering an error in the default implementation in a base class. One of the main things a lot of PHP programmers I've worked with hate is waiting for code to hit production and encountering a runtime error w/ something that could have been caught at compile time. I know the notion of compile time in a scripting language like PHP is much less removed from that of C++, Java etc, however there is a notion of it there, obviously. Also, I would suggest this feature be optional, so there is no need to use it if you don't like it. But for those of us who would like to defer as much type checking to the compiler as possible so we don't need runtime checks all over our code or prayers that we've tested every line before production, it would certainly be nice. Lastly, you may know that traits will allow PHP programmers to move away from the delegate pattern which is a common workaround to multiple inheritance at this point. However, in speaking with a colleague over the concept I'm proposing yesterday we discovered the delegate model actually does allow you to specify which class/interface the delegate is used w/, it would be sad not to see comparable support in the trait feature which will mostly eliminate the need for the delegate pattern, see my quick example. ?php class MainClass { private $_oDelegate = null; function addDelegate() { $this-_oDelegate = new Delegate($this); } } class Delegate { private function $_oMain = null; /// delegate gets to say what it can be used with via type hinting function __construct(MainClass $oMainClass) { $this-_oMain = $oMainClass; } } ? Imagine how much cleaner this could be w/ traits, yet just as expressive ?php class MainClass { use Delegate; } trait Delegate require MainClass { ... } ? -nathan As a note, I'm not strongly opposed to this proposal, since I don't think it would do any harm. It just seems to me like a kitchen sink feature. The issue for me is that traits, as I understand them, are there primarily for horizontal code re-use via compile-time copy/paste. With that in mind, I feel like the developer is responsible for making sure the methods they copy into their classes make sense, just as they would have to do if they physically copied and pasted them. Copy paste itself leads to duplicated unmaintainable code, so traits are introduced (among other reasons) to prohibit this practice. Why not take it a step further and let a trait definition be as expressive as possible, eliminating ambiguity, right out of the gate? I think your example above isn't quite what you meant to show, since you're requiring a specific class and not an interface (since PHP only allows one class definition for a class name, you're not gaining anything via traits, since the trait could only be used for that specific class, in which case why not just have the code in the class in the first place?). In retrospect Chad, that's a good point, and perhaps there is no reason to allow marking of classes as required by traits. If we take your example in a more general case using interfaces, I still can't see what the benefit is. All it does is provide a more explicit and immediate error message for developers (e.g. instead of method not found error when the bad method call is made at runtime, you get a classes using trait trait must implement
Re: [PHP-DEV] Traits expecting interfaces implicitly leads to expensive runtime checks
On Fri, Dec 10, 2010 at 2:42 PM, Matthew Weier O'Phinney weierophin...@php.net wrote: On 2010-12-10, Nathan Nobbe quickshif...@gmail.com wrote: --0016e6d7e101e083a4049714bad3 Content-Type: text/plain; charset=UTF-8 On Fri, Dec 10, 2010 at 12:55 PM, Matthew Weier O'Phinney weierophin...@php.net wrote: On 2010-12-10, Nathan Nobbe quickshif...@gmail.com wrote: --0016e6dbe7fb8861a1049712ad63 Content-Type: text/plain; charset=UTF-8 On Fri, Dec 10, 2010 at 11:04 AM, Chad Fulton chadful...@gmail.com wrote: On Fri, Dec 10, 2010 at 9:29 AM, Nathan Nobbe quickshif...@gmail.com wrote: On Fri, Dec 10, 2010 at 10:15 AM, Martin Wernstahl m4r...@gmail.com wrote: First i have to say that I am not a PHP internals developer, but as a user I think it would maybe be better to just let the trait use the implements keyword, and copy that to the classes utilizing the trait? This is actually in the RFC as a rejected proposal http://wiki.php.net/rfc/traits#rejected_features But what I'm talking about is something different. We're not trying to say 'these are the methods implemented in the trait', rather, 'this trait expects a class it is used with to be of a certain type or implement a certain interface' for the trait to do its job. -nathan Shouldn't the burden be on the programmer to make sure the trait works with the class using it rather than on the compiler? If they try to use a trait that requires methods that don't exist, it will error out anyway, so it won't be difficult to debug. Well I know PHP is a dynamic language but what about all the compile time features that have come along over the years. The abstract keyword for example vs. the PHP4 way of implementing an 'abstract' method which was triggering an error in the default implementation in a base class. One of the main things a lot of PHP programmers I've worked with hate is waiting for code to hit production and encountering a runtime error w/ something that could have been caught at compile time. I know the notion of compile time in a scripting language like PHP is much less removed from that of C++, Java etc, however there is a notion of it there, obviously. To me, putting this into the language feels like overkill. Unless you're using an opcode cache, the notion of compile time as a differentiation from runtime in PHP has little relevance -- you still only find out when the script executes. *Only* if you hit the line of code at runtime that would destroy your script; often times this doesn't happen until it's too late, and the code has made it to production. That's what good testing is about -- exercising all the expected behaviors of your code. If you hit an unexpected behavior in production, you add a test to your suite that reproduces it, fix it, and re-deploy. Right, and implementing an interface or subclassing an abstract class does not require a unit test in order to determine if I've at least met the obligations set forth by the interface or abstract class. The basic idea of a unit test is to write meaningful tests that actually offer you some milage for your time. I mean sure, I could write tests for setters and getters, but that's pretty much a waste of time compared to writing tests that actually get into semantics the class aims to provide. And there is a notion of compile time in PHP, I'm not sure what it's referred to by the internals group, but abstract methods and interfaces definitely constitue compile time checks to me. There's already a way to mitigate this as well: write a testing suite for your application, and exercise it often. If you write your tests well (targeting the discrete behaviors of your application), then most likely they'll catch such errors -- allowing you to fix them before you deploy. Right, so you have to do tons of extra work (writing unit tests) which have to actually test every potential line of failure, when this could just simply be caught up front w/o any second guessing whether or not you've covered all cases in your tests. Writing tests should not be considered tons of extra work; it should be considered a basic part of development. Shrug, taken out of context. I'm sure you can see how writing an extra word in the trait definition is much less work than including a unit test suite in your project and then a test against each class that uses the trait.., IMO, *that* is a ton of extra work. Even in the context of unit test writing a compile time check would eliminate the need of writing what I would consider bolier plate unit tests for traits. It's like, well I just wrote a trait, now any class I write against it I should go ahead and test that it provides all the methods for said trait .. that's just a waste of time
Re: [PHP-DEV] Traits expecting interfaces implicitly leads to expensive runtime checks
On Thu, Dec 9, 2010 at 1:09 AM, Stefan Marr p...@stefan-marr.de wrote: Hi Nathan: On 09 Dec 2010, at 08:44, Nathan Nobbe wrote: Hi, I think traits will lend themselves to frequent runtime checking against the type of class in which they were used. Consider a trait designed for use with an Iterator class; the first thing might be to check the type of $this. Why would you need such a check? To avoid a fatal error at runtime. You want to ensure that the class that is using your trait obeys a certain interface, right? Not really, it's so the trait can guarantee the class it has been used with implements a given interface that it may need to accomplish its job. More specifically, you need it to implement a number of methods of an interface, correct? So, why not asking for it explicitly? ?php trait InnerIteratorImpl { abstract function next(); public function apply() { do somthing with $this-next() ... } } ? Does that what you want it to do? Not really, in this example above the trait is self-contained, implementing all the methods of a particular interface so it's reasonable to expect from one of the methods in the trait, another of the Iterator interface to be there. What I'm getting at is the scenario when a trait is designed to be used in concert with the class in which it is being used. In this case the trait expects certain functions to be available on the class in which it is used with. If the methods aren't there (or checked for at runtime) a fatal error is raised. A quick example ?php class A { use AHelper; function blah() {} } trait AHelper { function meh() { // hoping we get used w/ instances of A ... return $this-blah() * 5; } } class B { use AHelper; /// waiting for a runtime error if blah() is ever called .. } ? Do you see what I mean? -nathan
Re: [PHP-DEV] Project Management
On Wed, Dec 1, 2010 at 1:12 AM, Lester Caine les...@lsces.co.uk wrote: While a little off topic, I feel that it is worth our having a discussion on project management. Source control, and the like ... Current discussion on 'git' highlights the fact that there is no clear solution to source control. The switch TO SVN was pushed through even though a few problems with that were then coming to light and now that move is probably questionable. Projects that had not jumped have now put that on hold since DVCS is obviously the next step, but none of the current solutions are ideal and each have as many minus as plus points. The real problem that I am finding is that all of these 'systems' work on the basis that we are handling source code which will then be compiled. Managing code that is not compiled becomes something of a mess especially when it would be nice to maintain file versions in those script files, and running a 'build' process to restore the tidy CVS type headers then makes things difficult between different DVCS systems. Many core DVCS developers simply do not understand that there is NOT a final binary distribution? Personally I've been getting into something of a mess trying to manage distributing PHP projects that are version controlled via hg since the only real way is to install hg on all the target machines ... something which is not really practical? I do get told to just use rsync to clone the files to other machines, which is a little impractical when the target machines are windows or don't have internet access. Fortunatly the CVS original is still running and back porting is sorting out the distribution problem! git archive cranks out a single file representing any commit in the repository, it can even format the archive w/ zip for the windows folks ;) On top of that managing the release process to combine updates from other distributed code bases has already created the situation where there are 'sub-projects' which it is now difficult to integrate back with the original main project. this happens all the time in centralized models as well, its just a matter of how often the code is being synchronized. in the case of dvcs, it's likely the peripheral project has not re-based or merged recently / frequently enough. and on top of that, the main project maintainers didn't see enough merit to ever sync up the peripheral project anyway.., so the onus would rest on the developers of the sub-project. not too unlike those good ol svn days at the office.., where someone wouldn't commit for weeks at a time, wouldn't even update very often, and then shocked to find out their code isn't merging completely w/ other new features and production support going on the whole time... if you think about it, having the projects disjoint like that is actually doing favor to the maintainers of the main project. less clutter in the 'official' repo. this is actually impossible to attain in svn, since all branches in svn are tied directly to the central server. I think we need to start a more integrated discussion on the whole of this project management process so that we can come up with a usable approach that works more generally for scripted language projects? Add IDE's like Eclipse and to some extent Zend framework, and there is another layer of complexity that further fragments the overall requirements. I've never had a problem with 'merging' simply because Eclipse/BC handles that and is currently allowing me to untangle the current niggles! graphical tools are nice, but I think the underpinnings are more important in deciding which is best for use. svn merging has performance bound tightly to the network meaning, if you aren't running the merge on the box actually hosting svn, you'd better be running it from a box physically close or w/ a really high bandwidth connection. of course dvcs lets you run fast merges no matter where you are and let the actual synchronization run after the merge is done, like while you're sleeping say :) also, the svn merge tracking is convoluted, there's a lot to have to know at the user level just to get around it. I've found it a lot easier to trust the merges from git than I ever did svn, and actually ran svn 1.5 for a while with their merge-tracking, which doesn't work correctly without proper user interaction read: --reintegrate .. I'm not a core php dev, but I have dealt w/ a lot of version control, and frankly moving to git from svn was an even better move than cvs to svn, no doubt about it. -nathan
[PHP-DEV] Proposed - Integrated inner iterator support for Iterator classes
Hi everyone, I've been taking another look at iterators lately, and compiled trunk and started experimenting with traits. I also looked at an old mail from Marcus regarding iterator_apply, and find myself wondering why there isn't just an 'apply' method as part of the Iterator hierarchy itself. Although PHP had support for the pseudo-type callback when the Iterator interface was introduced, I'm not sure why an 'apply' function would have been omitted from the original Iterator interface. Clearly with iterator_apply out there, there is no functional gain by adding a method into the Iterator hierarchy, however I think it would be more cohesive with the OO paradigm the Iterator hierachy presents .. there is already array_walk and friends for the global function gang :) And now with closures the idea of an 'apply' method is even more enticing .. yes I'm thinking of Javascript code like JQuery's each() ... I can tell why it wouldn't have been added after the original interface was in the wild though, because changing the interface would break tons of client code. However a second interface could be added and all client code would continue to function interface InnerIterator { function apply($mCallback [, mixed $...]); } Rather than extend Iterator, InnerIterator should be left independent so it can be incorporated into implementors of OuterIterator (see below). Then concrete Iterator(s) could implement this new interface as well class ArrayIterator implements Iterator, InnerIterator { … } I'm not sure what the best implementation at the engine level would be, but with the advent of traits that would clearly be one option, a simple implementation could be something like trait InnerIteratorImpl { public function apply($mCallback) { $aArgs = func_get_args(); array_shift($aArgs); $aCallbackArgs = array_merge(array($this), $aArgs); return iterator_apply($this, $mCallback, $aCallbackArgs); } } Then the ArrayIterator definition could become class ArrayIterator implements Iterator, InnerIterator { use InnerIteratorImpl; ... } I hardly doubt this is necessary inside the engine, as I'm sure there can be a common C function which is used to implement the interface, but that would be for more educated people to decide. Classes which implement IteratorAggregate (ArrayObject for example) would then return implementors of InnerIterator, which still implement Iterator as they originally did. Classes which implement OuterIterator could now also implement InnerIterator as well, and the 'apply' method in that case can simply delegate to the wrapped Iterator as they currently do for implemented Iterator methods. class CachingIterator implements OuterIterator, InnerIterator { public function apply($mCallback) { return $this-getInnerIterator()-apply(func_get_args()); } } A quick example from userspace with the addition $oArrayObj = new ArrayObject(array(5, 4, 3, 2, 1)); $oArrayObj-getIterator()-apply(function(Iterator $oIt) { var_dump($oIt-current()); return true; }); At the end of the day it's just syntactic sugar since iterator_apply is there, but in my book it would be welcome sugar ;) I would also argue that even with traits, implementing this notion in userspace is slower (needless conversion) and messy, imagine a subclass of ArryObject for example that implements InnerIterator, inside of getIterator, it has to convert the ArrayIterator to a new userspace class InnerArrayIterator or some such, which implements InnerIterator, before returning it. Your thoughts appreciated! -nathan
[PHP-DEV] Revise callback Psuedo-type to support new Closure class ?
Hi all, I had a thought this morning and would like some feedback. Don't you think it would make sense to allow the callback psuedo-type to also allow the new Closure class to be an acceptable data type? A simple example that would be nice to have working would be ?php $fClosure = function($val, $key) { echo $key = $val . PHP_EOL; } $aNumbers = array(5, 4, 3, 2, 1); array_walk($aNumbers, $fClosure); ? Thoughts ? -nathan
[PHP-DEV] Re: Revise callback Psuedo-type to support new Closure class ?
Ummm... never mind! Sorry for the noise! -nathan On Wed, Nov 24, 2010 at 11:00 AM, Nathan Nobbe quickshif...@gmail.comwrote: Hi all, I had a thought this morning and would like some feedback. Don't you think it would make sense to allow the callback psuedo-type to also allow the new Closure class to be an acceptable data type? A simple example that would be nice to have working would be ?php $fClosure = function($val, $key) { echo $key = $val . PHP_EOL; } $aNumbers = array(5, 4, 3, 2, 1); array_walk($aNumbers, $fClosure); ? Thoughts ? -nathan
[PHP-DEV] Another question on traits
Hi, Simas' question yesterday lead me to take a look at the RFC on the wiki and I have a quick question. Specifically on the 'Rejected Features' - 'Interfaces Propagation' section. So it sounds like implementing an interface directly with a trait has been shot down, what I wonder about is will it still work if a class implements an interface and uses a trait which provides the functions in said interface? ?php interface IHello { public function sayHello(); } trait SayHello { public function sayHello() { echo 'hello world'; } } class MyHelloWorld implements IHello { use SayHello; } $o = new MyHelloWorld(); var_dump($o instanceof IHello); // bool (true) ? An explicit way to leverage traits in the inheritance tree... Is that accurate, or will that not work either? thx, -nathan
Re: [PHP-DEV] Intermittent problem: can't write to properties of $this
On Thu, Oct 21, 2010 at 5:04 PM, Tim Steiner tstei...@nerdclub.net wrote: Greetings, I'm currently trying to troubleshoot an intermittent problem on one of our servers. After some time of running just fine (usually a couple of hours), scripts will start throwing the warning Attempt to assign property of non-object when writing to a property of the $this object. Once it starts, it seems to keep happening every few requests (with other requests running as expected). The poster at http://www.zfforums.com/zend-framework-components-13/core-infrastructure-19/warning-attempt-assign-property-non-object-zend_config-5469.htmlseems to be having the same issue. I've traced the warning output to line 576 of Zend/zend_execute.c, which means that something is happening to the write_property of the object. At this point, I don't have enough knowledge of the internals to continue tracking this bug down. Any help would be appreciated. Tim, this sounds much more like a typical userspace issue than an internals one. You might have better luck getting help if you start out on the php-general list. -nathan
[PHP-DEV] Using child classes/interfaces as desired type hints
Hi, Probly rehashing an old conversation here, but I'm wondering why the following isn't supported ?php abstract class AbstractServer {} class ConcreteServer extends AbstractServer {} abstract class AbstractClient { abstract function doStuff(AbstractServer $o); } class ConcreteClient extends AbstractClient { function doStuff(ConcreteServer $o) {} } ? This results in a fatal Fatal error: Declaration of ConcreteClient::doStuff() must be compatible with that of AbstractClient::doStuff() in /Users/quickshiftin/gitRepos/timberline/php-api-v15-client/testOverride.php on line 11 I was reading a few posts from way back when http://marc.info/?t=10777490481r=1w=2 yet still find myself wondering. I think it can be said here that if there's a contract defined by AbstractClient::doStuff, that same contract is honored by ConcreteClient::doStuff. I also think changing the language to support this notion wouldn't raise BC issues for the most part (at all?) since at the moment you're forced to move to the lowest common denominator in the tree, in this case class ConcreteClient extends AbstractClient { function doStuff(AbstractServer $o) {} } your feedback appreciated, -nathan
[PHP-DEV] Bug in 5.3 __invoke() magic method?
Hi, Started using 5.3 and stumbled into what appears to be a bug with the __invoke() magic method. It works fine if used in an object for a class defining __invoke() is stored in a local variable, however when storing said object as an instance variable, a fatal is raised. See my example below. ?php class A { public function __invoke() { echo __CLASS__ . PHP_EOL; } } class B { private $a = null; public function __construct() { $this-a = new A(); $this-a(); } } $a = new A(); $a(); $b = new B(); ? Output: A Fatal error: Call to undefined method B::a() in /Users/quickshiftin/gitRepos/timberline/ct-rip/test-callable.php on line 17 Expected Output: A A thx, -nathan
Re: [PHP-DEV] Bug in 5.3 __invoke() magic method?
On Wed, Sep 29, 2010 at 2:56 PM, Stas Malyshev smalys...@sugarcrm.comwrote: Hi! public function __construct() { $this-a = new A(); $this-a(); Here you are calling method a() of object $this. Such method does not exist. No bug here. Methods are properties are different things. Stas, thanks for this. Seems that w/ __invoke() in 5.3 if a method property is_callable then the engine should check for that and call it. I realize the problem now though, in php instance variables can have the same identifier as instance methods therefore collisions could exist, for example class B { function __invoke() {} } class A { public $c = null; function c() {} } $a = new A(); $a-c = new B(); $a-c(); seems i got the notion this would work from javascript, however i also realize the reason it works there, only a single identifier is allowed which would map to either a scalar or a function object and in the later case would be invokable. the implementation in php make sense to me now. thanks for your time, -nathan
Re: [PHP-DEV] autoloading and undefined class constants
On Sun, Jul 5, 2009 at 10:21 PM, Ben Bidner b...@vuetec.com wrote: per the manual, exceptions thrown in an autoload method are swallowed, and an E_ERROR is triggered by php. http://us2.php.net/manual/en/language.oop5.autoload.php I have read that note before, and wondered exactly what it was referring to since you can throw exceptions within an autoloader and catch them (or have your exception handler do whatever it needs to do with them). ?php function autoloader($className) { echo autoloading . PHP_EOL; throw new Exception(Fail); } spl_autoload_register(autoloader); try { // Exception $obj = new NonExistentClass; } catch(Exception $e) { echo caught . PHP_EOL; } try { // Exception $const = constant(NonExistentClass::NON_EXISTENT_CONSTANT); } catch(Exception $e) { echo caught . PHP_EOL; } try { // Fatal error $const = NonExistentClass::NON_EXISTENT_CONSTANT; } catch(Exception $e) { echo never happens . PHP_EOL; } ? Will output: autoloading caught autoloading caught autoloading PHP Fatal error: Undefined class constant on both my systems (mentioned in reply to rob) the script fatals after the first autoloading, just like the manual says.. nat...@trident2:~$ php testcode.php autoloading Fatal error: Class 'NonExistentClass' not found in /home/nathan/testcode.php on line 41 -nathan
Re: [PHP-DEV] autoloading and undefined class constants
On Sun, Jul 5, 2009 at 8:49 PM, Ben Bidner b...@vuetec.com wrote: Hi folks, Just looking for a quick clarification on how class constant look ups are performed internally under circumstances when an autoload function is also called. Consider the following example: ?php function autoloader($className) { throw new Exception(Fail); } spl_autoload_register(autoloader); ? ?php // Exception $obj = new NonExistantClass; ? ?php // Fatal error $const = NonExistantClass::NON_EXISTANT_CONSTANT; ? I would have assumed that since the autoloader threw an exception while attempting to load the non existant class, that internally, there would be no attempt to access the non existant constant (since surely that comes after the exception was thrown???) and we would get the Exception, rather than a Fatal error. Intended or a design error? per the manual, exceptions thrown in an autoload method are swallowed, and an E_ERROR is triggered by php. http://us2.php.net/manual/en/language.oop5.autoload.php personally, i dont know why it works this way.. even if you register an error handler, you cant handle it from user-space, b/c set_error_handler() only lets you handle E_USER_ERROR.. there are 2 issues this presents, 1. if your autoloading logic creates a message that it would pass through to higher level code, via exceptions or errors, they are swallowed, so you dont know what went wrong. 2. if you call die() you can log the message, however youll not be able to leverage standard error handling code here, at least not via a thrown exception or triggered error the only solution ive found is to invoke the standard error handling code directly from the autoloading logic. imo, this defeats the purpose of the loose coupling errors and exceptions provide. one of the reasons its really painful is because the autoloader is startup code.., which means you cant leverage it to load its dependecies, which means your error logging code cant leverage the autoloading logic iff the autoloading logic has to call the error handling logic directly:( when i say 'standard error handling logic' i mean like loading up a static html page, or similar. i think, since failures in autoload result in an E_ERROR, it would at least make sense to allow user-space to trigger E_USER_ERROR, which PHP could allow to pass through the autoload method untouched. i think this is reasonable, b/c E_USER_ERROR still interrupts program execution, and then userspace could leverage the same error handling code it does for everything else when problems occur with autoloading. id seen some posts on php.net about using output buffering to be able to trap E_ERROR but then came to discover that output buffering has been disabled on the cli since like 4.3.5, so the example code like, ?php ob_start(); call_fake_function(); ? would blow up w/ a fatal on all my installations. id post on php-general about it, but im more curious to see what internals folks think about it. -nathan
Re: [PHP-DEV] non static function called as static one
On Wed, Mar 11, 2009 at 3:16 PM, Olivier Doucet webmas...@ajeux.com wrote: Hello, I posted the same topic on the general mailing list, but it appears this can be posted here, as it is open to feedbacks and is about PHP implementation of static functions. I'm wondering if the following behaviour is a bug or a feature. The case is quite complex, so let me explain my point of view. here is the source : ?php class MyTest { public function myfunc() { echo get_class($this); } } class MySecondTest { public function test() { MyTest::myfunc(); } } $test = new MySecondTest(); $test-test(); //output: MySecondTest ? not sure if this was mentioned on the general list but, i believe what youre describing is documented in the manual under php5 classes/objects - the basics: http://www.php.net/manual/en/language.oop5.basic.php $this is a reference to the calling object (usually the object to which the method belongs, but can be another object, if the method is called statically http://www.php.net/manual/en/language.oop5.static.php from the context of a secondary object). -nathan
Re: [PHP-DEV] non static function called as static one
On Wed, Mar 11, 2009 at 4:40 PM, Olivier Doucet webmas...@ajeux.com wrote: Hi, not sure if this was mentioned on the general list but, i believe what youre describing is documented in the manual under php5 classes/objects - the basics: http://www.php.net/manual/en/language.oop5.basic.php $this is a reference to the calling object (usually the object to which the method belongs, but can be another object, if the method is called statically http://www.php.net/manual/en/language.oop5.static.php from the context of a secondary object). -nathan I know this behaviour is fully documented, but I was more concerned about is it a 'normal' behaviour ?. How can a programmer controls the class he wrote, and make it absolutely bugproof ? How can he detect his function was called in a static context and forbid it (or write specific code for) ? well, the access to $this of the secondary object is limited. so the only way it really does anything useful is if member variables you wish to access are marked as public; making it mostly useless imo.. but anyway all youd need to do is mark member vars as protected or private. (personally, i think it should be able to access protected vars, since the class which invokes the other statically is essentially sanctioning access to its instance variables). ?php class A { public function showOtherClassInstanceVar($varname) { var_dump($this-$varname); } } class B { public $a = 1; protected $b = 2; private $c = 3; public function dumpViaMixin() { A::showOtherClassInstanceVar('a'); A::showOtherClassInstanceVar('b'); A::showOtherClassInstanceVar('c'); } } $b = new B(); $b-dumpViaMixin(); --- outputs int(1) then the error log shows, [11-Mar-2009 17:01:03] PHP Fatal error: Cannot access protected property B::$b in /Users/nnobbe/testDelegation.php on line 5 [11-Mar-2009 17:01:03] PHP Stack trace: [11-Mar-2009 17:01:03] PHP 1. {main}() /Users/nnobbe/testDelegation.php:0 [11-Mar-2009 17:01:03] PHP 2. B-dumpViaMixin() /Users/nnobbe/testDelegation.php:22 [11-Mar-2009 17:01:03] PHP 3. A-showOtherClassInstanceVar() /Users/nnobbe/testDelegation.php:16 so you should be able to protect your classes w/o too much trouble. -nathan
Re: [PHP-DEV] Adding/Updating ZVal Arrays to Object
On Fri, Feb 20, 2009 at 12:31 PM, Matthew C. Rice mr...@rcs.us wrote: Hello everyone, I am building a custom PHP Extension. It is object based, and while the documentation seems to be lacking a little on this aspect in extensions, I haven't let that slow me down. I have used other extensions as examples, and done a great deal of searching around to find everything I have needed until now. I currently have the following http://pastebin.com/m74c98b43 ( the start method ) in my classes __construct ( I actually use PHP_MALIAS to alias __construct to the function ) .. This works perfect. It creates a array in the object, just as I expect it to. I can even print out the number of elements and their values in the debug function by passing $Obj-Property to it The problem I am having is that I can't seem to figure out a way to append values on to the ZVal Array in another PHP_METHOD(). I have tried combinations of zend_hash_find() zend_hash_update() to no avail. Is there anyone that might be able to point me in the right direction as to how to do this? i think mainly you just need to read the zval from the instance, operate on it, then update the instance. heres some working code from the extension ive been working on, /* {{{ proto public void MacroCommand::addSubCommand(string commandClassRef) add a subcommand to this MacroCommand */ PHP_METHOD(MacroCommand, addSubCommand) { zval *this, *subCommands, *subCommand; char *rawSubCommand; int rawSubCommandLength; if( zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, s, rawSubCommand, rawSubCommandLength) == FAILURE) { RETURN_NULL(); } MAKE_STD_ZVAL(subCommand); ZVAL_STRINGL(subCommand, rawSubCommand, rawSubCommandLength, 1); this = getThis(); zend_class_entry *this_ce = zend_get_class_entry(this); subCommands = zend_read_property(puremvc_macrocommand_ce, this, subCommands, sizeof(subCommands)-1, 1 TSRMLS_CC); ZVAL_ADDREF(subCommand); add_next_index_zval(subCommands, subCommand); zend_update_property(puremvc_macrocommand_ce, this, subCommands, sizeof(subCommands)-1, subCommands TSRMLS_CC); } /* }}} */ and heres my unit test for this method, --TEST-- MacroCommand::addSubCommand(), ensure addSubCommand actually stores the ICommand in an internal array --SKIPIF-- ?php if (!extension_loaded(pure_mvc)) print skip; ? --FILE-- ?php class SubCommand {} class MyMacroCommand extends MacroCommand { protected function initializeMacroCommand() { $this-addSubCommand('SubCommand'); } } $macroCmd = new MyMacroCommand(); var_dump($macroCmd); ? --EXPECT-- object(MyMacroCommand)#1 (2) { [facade:protected]= string(0) [subCommands:private]= array(1) { [0]= string(10) SubCommand } } hope this helps, -nathan
Re: [PHP-DEV] Adding/Updating ZVal Arrays to Object
On Fri, Feb 20, 2009 at 3:02 PM, Matthew C. Rice mr...@rcs.us wrote: Nathan, Thanks a bunch. That was exactly what I was looking for. word Is there any place you would consider a good resource to learn/get documentation for these functions? my secret weapon, http://www.amazon.com/Extending-Embedding-PHP-Developers-Library/dp/067232704X :D but youll still have to do all the things youre doing now. digging through other extensions, looking through the code under the Zend directory and so forth.. the book just makes things *way* easier to get the ball rolling. -nathan
Re: [PHP-DEV] Re: Adding a property to an object
On Fri, Feb 20, 2009 at 3:45 PM, Matthew C. Rice mr...@rcs.us wrote: David, I personally have not read that book, as I actually heard pertaining to objects ( where I too have had some issues ) it wasn't really a terrific reference. Though if this is not the case, I would love to hear otherwise.. i found the oop section a bit lacking. one of the main issues is that the chapters are titled php4 objects, php5 objects, but really overall material is spread between the two chapters. like the section working with instances in the php4 objects chapter. where was its counterpart in the php5 objects chapter? what you begin to realize is a lot of the things are exactly the same, but i thought at least the organization was a bit awkward. also, im not sure if when zend_call_method and its variants appeared, i suspect after the books publication perhaps. that seems to be the way to go, calling class/object methods. the book illustrates call_user_function() which by comparison is really painful in working w/ objects imo. all-in-all though id say the book is solid. ive been able to accomplish everything ive wanted so far with my first extension. i dunno, ive not worked with a lot of C api's so far, but i think id probly have struggled getting started w/o the book. -nathan
Re: [PHP-DEV] zend_call_method() - support for up to 4 parameters
did you guys see the other patch i posted yesterday? i re-read Johannes' first reply yesterday and saw the bit about a second api for a zend_call_method with a variable number of parameters. so a made a new function then re-implemented zend_call_method based on that. heres the patch (easier to read on pastebin). http://pastebin.com/m4fd58822 im sure it could be tweaked, but i think the main point is using an array rather than va_list to support the varialbe arg list. is this any better than the first one ? thanks, -nathan
Re: [PHP-DEV] zend_call_method() - support for up to 4 parameters
On Wed, Feb 18, 2009 at 6:16 AM, Johannes Schlüter johan...@php.net wrote: But I don't think that a new limitation is any better: Tomorrow we have to change it again as somebody has a reason to use 5 parameters, so if it is changed it should be changed to take any number of arguments and no fixed limit (or add a new API for that) that does seem ideal to me, but in the last thread, marcus was clear that an emalloc / va_list solution was unacceptable. that was last january.. has anything changed in that regard since? also, it sounded like he was saying a simple solution for up to 4 parameters would be alright. mainly i thought it would be nice to get it into the code for 5.3 before we'd have to wait for another major release in order to get something included. yes, perhaps the function would need updating again in the future, but since people are using macros rather than zend_call_method directly it wouldnt be too bad right? -nathan
[PHP-DEV] zend_call_method() - support for up to n params - no va_list
On Wed, Feb 18, 2009 at 6:16 AM, Johannes Schlüter johan...@php.net wrote: But I don't think that a new limitation is any better: Tomorrow we have to change it again as somebody has a reason to use 5 parameters, so if it is changed it should be changed to take any number of arguments and no fixed limit (or add a new API for that) given Johannes' feedback this morning, i created another patch, which adds zend_call_method_va(), it accepts an array of zvals. then i changed zend_call_method() to build the array and call zend_call_method_va(). it seems like this meets all the objectives. . support for n parameters . no emalloc calls . no va_list usage . zend_call_method() backwards compatible (lesser extent) your feedback appreciated, -nathan (and i did the diff in the right direction this time :D) --- zend_interfaces.ORIG.c2009-02-17 20:24:47.0 -0700 +++ zend_interfaces.c2009-02-18 11:44:53.0 -0700 @@ -29,9 +29,10 @@ ZEND_API zend_class_entry *zend_ce_arrayaccess; ZEND_API zend_class_entry *zend_ce_serializable; -/* {{{ zend_call_method + +/* {{{ zend_call_method_va Only returns the returned zval if retval_ptr != NULL */ -ZEND_API zval* zend_call_method(zval **object_pp, zend_class_entry *obj_ce, zend_function **fn_proxy, char *function_name, int function_name_len, zval **retval_ptr_ptr, int param_count, zval* arg1, zval* arg2 TSRMLS_DC) +ZEND_API zval* zend_call_method_va(zval **object_pp, zend_class_entry *obj_ce, zend_function **fn_proxy, char *function_name, int function_name_len, zval **retval_ptr_ptr, int param_count, zval** params TSRMLS_DC) { int result; zend_fcall_info fci; @@ -39,11 +40,6 @@ zval *retval; HashTable *function_table; -zval **params[2]; - -params[0] = arg1; -params[1] = arg2; - fci.size = sizeof(fci); /*fci.function_table = NULL; will be read form zend_class_entry of object if needed */ fci.object_ptr = object_pp ? *object_pp : NULL; @@ -107,6 +103,19 @@ } /* }}} */ +/* {{{ zend_call_method + Only returns the returned zval if retval_ptr != NULL */ +ZEND_API zval* zend_call_method(zval **object_pp, zend_class_entry *obj_ce, zend_function **fn_proxy, char *function_name, int function_name_len, zval **retval_ptr_ptr, int param_count, zval* arg1, zval* arg2 TSRMLS_DC) +{ +zval **params[2]; + +params[0] = arg1; +params[1] = arg2; + +return zend_call_method_va(object_pp, obj_ce, fn_proxy, function_name, function_name_len, retval_ptr_ptr, param_count, params TSRMLS_CC); +} +/* }}} */ + /* iterator interface, c-level functions used by engine */ /* {{{ zend_user_it_new_iterator */ --- zend_interfaces.ORIG.h2009-02-17 20:24:36.0 -0700 +++ zend_interfaces.h2009-02-18 11:28:55.0 -0700 @@ -38,6 +38,8 @@ zval *value; } zend_user_iterator; +ZEND_API zval* zend_call_method_va(zval **object_pp, zend_class_entry *obj_ce, zend_function **fn_proxy, char *function_name, int function_name_len, zval **retval_ptr_ptr, int param_count, zval** params TSRMLS_DC); + ZEND_API zval* zend_call_method(zval **object_pp, zend_class_entry *obj_ce, zend_function **fn_proxy, char *function_name, int function_name_len, zval **retval_ptr_ptr, int param_count, zval* arg1, zval* arg2 TSRMLS_DC); #define zend_call_method_with_0_params(obj, obj_ce, fn_proxy, function_name, retval) \
[PHP-DEV] zend_call_method() - support for up to 4 parameters
hi, recently, working on an extension, i wanted to call a method w/ 3 params, and as you know, zend_call_method only supports 2 parameters at most. i came across this thread in the archives, http://marc.info/?l=php-internalsm=120179690310419w=2 so i tossed together a quick patch w/ no emalloc or va_list against the latest 5.3 snapshot. what do you think? -nathan --- zend_interfaces.c2009-02-17 20:50:35.0 -0700 +++ zend_interfaces.ORIG.c2009-02-17 20:24:47.0 -0700 @@ -31,7 +31,7 @@ /* {{{ zend_call_method Only returns the returned zval if retval_ptr != NULL */ -ZEND_API zval* zend_call_method(zval **object_pp, zend_class_entry *obj_ce, zend_function **fn_proxy, char *function_name, int function_name_len, zval **retval_ptr_ptr, int param_count, zval* arg1, zval* arg2, zval* arg3, zval* arg4 TSRMLS_DC) +ZEND_API zval* zend_call_method(zval **object_pp, zend_class_entry *obj_ce, zend_function **fn_proxy, char *function_name, int function_name_len, zval **retval_ptr_ptr, int param_count, zval* arg1, zval* arg2 TSRMLS_DC) { int result; zend_fcall_info fci; @@ -39,12 +39,10 @@ zval *retval; HashTable *function_table; -zval **params[4]; +zval **params[2]; params[0] = arg1; params[1] = arg2; -params[2] = arg3; -params[3] = arg4; fci.size = sizeof(fci); /*fci.function_table = NULL; will be read form zend_class_entry of object if needed */ --- zend_interfaces.h2009-02-17 20:51:22.0 -0700 +++ zend_interfaces.ORIG.h2009-02-17 20:24:36.0 -0700 @@ -38,22 +38,16 @@ zval *value; } zend_user_iterator; -ZEND_API zval* zend_call_method(zval **object_pp, zend_class_entry *obj_ce, zend_function **fn_proxy, char *function_name, int function_name_len, zval **retval_ptr_ptr, int param_count, zval* arg1, zval* arg2, zval* arg3, zval* arg4 TSRMLS_DC); +ZEND_API zval* zend_call_method(zval **object_pp, zend_class_entry *obj_ce, zend_function **fn_proxy, char *function_name, int function_name_len, zval **retval_ptr_ptr, int param_count, zval* arg1, zval* arg2 TSRMLS_DC); #define zend_call_method_with_0_params(obj, obj_ce, fn_proxy, function_name, retval) \ -zend_call_method(obj, obj_ce, fn_proxy, function_name, sizeof(function_name)-1, retval, 0, NULL, NULL, NULL, NULL TSRMLS_CC) +zend_call_method(obj, obj_ce, fn_proxy, function_name, sizeof(function_name)-1, retval, 0, NULL, NULL TSRMLS_CC) #define zend_call_method_with_1_params(obj, obj_ce, fn_proxy, function_name, retval, arg1) \ -zend_call_method(obj, obj_ce, fn_proxy, function_name, sizeof(function_name)-1, retval, 1, arg1, NULL, NULL, NULL TSRMLS_CC) +zend_call_method(obj, obj_ce, fn_proxy, function_name, sizeof(function_name)-1, retval, 1, arg1, NULL TSRMLS_CC) #define zend_call_method_with_2_params(obj, obj_ce, fn_proxy, function_name, retval, arg1, arg2) \ -zend_call_method(obj, obj_ce, fn_proxy, function_name, sizeof(function_name)-1, retval, 2, arg1, arg2, NULL, NULL TSRMLS_CC) - -#define zend_call_method_with_3_params(obj, obj_ce, fn_proxy, function_name, retval, arg1, arg2, arg3) \ -zend_call_method(obj, obj_ce, fn_proxy, function_name, sizeof(function_name)-1, retval, 3, arg1, arg2, arg3, NULL TSRMLS_CC) - -#define zend_call_method_with_4_params(obj, obj_ce, fn_proxy, function_name, retval, arg1, arg2, arg3, arg4) \ -zend_call_method(obj, obj_ce, fn_proxy, function_name, sizeof(function_name)-1, retval, 4, arg1, arg2, arg3, arg4 TSRMLS_CC) +zend_call_method(obj, obj_ce, fn_proxy, function_name, sizeof(function_name)-1, retval, 2, arg1, arg2 TSRMLS_CC) ZEND_API void zend_user_it_rewind(zend_object_iterator *_iter TSRMLS_DC); ZEND_API int zend_user_it_valid(zend_object_iterator *_iter TSRMLS_DC);
[PHP-DEV] type hint semantics; disagreement between phpt and manual
hi all, we are encountering an error in our code due to type hint semantics. php is allowing NULL values through a type hint for a class, however, if i read the manual, NULL, should only be allowed, if and only if, null is given as the default value for the formal parameter that is type-hinted. PHP 5 introduces Type Hinting. Functions are now able to force parameters to be objects (by specifying the name of the class in the function prototype) or arrays (since PHP 5.1). However, if NULLhttp://ch2.php.net/manual/en/language.types.null.phpis used as the default parameter value, it will be allowed as an argument for any later call. now, i have checked our code; there is no NULL default value, and there are no parents which mark a default value of NULL. so why would they be creeping through then.. ? well, i glanced at the phpt test, and its quite clear the tests are allowing NULL, Zend/tests/errmsg_013.phpt:errmsg: default value for parameters with array type hint can only be an array or NULL Zend/tests/errmsg_013.phpt:Fatal error: Default value for parameters with array type hint can only be an array or NULL in %s on line %d looking at the function prototype in this test, NULL is not specefied as the default value, so i dont think NULL should be allowed here anyway.. --TEST-- errmsg: default value for parameters with array type hint can only be an array or NULL --FILE-- ?php class test { function foo(array $a = s) { } } echo Done\n; ? --EXPECTF-- Fatal error: Default value for parameters with array type hint can only be an array or NULL in %s on line %d this taken from 5.2.6.RC3 source. it seems to me, either the source or the manual is wrong, but which one is it ?? personally, i would prefer it be the former in this case ;) FWIW, we are currently running php5.2.2 on centos5, but im pretty sure an upgrade to 5.2.6 will not change the semantics, since the phpt tests were the same in both the 5.2.2 5.2.6 source. -nathan
Re: [PHP-DEV] Re: Adding pecl/http to core
On Thu, Sep 25, 2008 at 12:24 AM, Jani Taskinen [EMAIL PROTECTED]wrote: Mike R wrote: Nathan Nobbe wrote: Michael Wallner wrote: Hi, I wonder what the general opinion is on adding pecl/http to the main PHP distribution? Many people have poked me in the past, so I guessed it's time to ask me and you that question once for all. +1 +1 FWIW, ditto. no to insult, but i find the curl api a bit painful. the http extension is a lot more api friendly for us oo folks out there. So pecl/http is actually ext/curl with OO API? for the most part, yes (i know it requires libcurl to build), but it has a set of functions in the global scope as well, like http_put() and http_post(). Why not merge the two then..? Or rather, replace ext/curl with pecl/http once latter has BC API for us non-oo folks out there.. im not sure the global function set in pecl/http interact w/ each other as do those in ext/curl. the two sets of functions may be mutually exclusive, but i suspect there could be some BC breakage in a merge of the two extensions. -nathan
Re: [PHP-DEV] Re: Adding pecl/http to core
On Wed, Sep 24, 2008 at 5:00 PM, Greg Beaver [EMAIL PROTECTED] wrote: Michael Wallner wrote: Hi, I wonder what the general opinion is on adding pecl/http to the main PHP distribution? Many people have poked me in the past, so I guessed it's time to ask me and you that question once for all. +1 +1 no to insult, but i find the curl api a bit painful. the http extension is a lot more api friendly for us oo folks out there. -nathan
Re: [PHP-DEV] TracingPHP
On Tue, Aug 26, 2008 at 6:57 AM, Jonathan Bond-Caron [EMAIL PROTECTED]wrote: On Mon Aug 25 06:28 PM, steve wrote: Has anyone had success compiling PHP with LLVM? I haven't tried it, here is a good summary: http://llvm.org/devmtg/2008-08/Lopes_PHP-JIT-InTwoDays.pdf In short, it is 'slower' but that seems to be without any caching of the bytecode Bytecode is not opcode: http://www.santosj.name/general/computers/byte-code-vs-op-code/ Right now, the most effective strategy to optimize php is executing opcodes using an opcode cache such as APC (facebook others use this). That's from my research, maybe someone can correct me here. Isn't using something like Zend Guard (converts code into opcode) then caching the opcodes essentially JIT? Even if opcode is not binary, it's still a fast intermediate form that gets translated into machine binary, isn't that JIT? i think that depends on what happens inside of php.. since i dont know the inner workings im guessing executing opcodes is pretty much the same thing every time, that is a certain opcode correlates to some precompiled code which is feed some variables at runtime. whereas in JIT, w/ java anyway, it actually takes bytecode (precompiled by the users [in .class files]) and compiles down to binary as certain pieces of bytecode are compiled. that compiled bytecode is then availble to the jvm through the remainder of that instances lifetime. so although php executes opcodes on an, as needed basis, i think the difference is that opcode correlate to precomipled binary, whereas w/ JIT, compilation (from opcode to binary) is actually occurring at runtime. http://schmidt.devlib.org/java/jit-compilers.html -nathan
Re: [PHP-DEV] __getStatic
On Thu, Aug 14, 2008 at 4:44 PM, Timm Friebe [EMAIL PROTECTED] wrote: Hi again, Attached you'll find an incomplete patch against PHP_5_3 to add this functionality. If you like it let me know and I can finish it. Darn, seems the list didn't like my text/plain attachment. Well, here we go: http://sitten-polizei.de/php/get-static.diff i think this is a great idea and a natural candidate for addition. -nathan
Re: [PHP-DEV] [RFC] E_USER_DEPRECATED
On Sun, Jul 20, 2008 at 2:02 PM, Lukas Kahwe Smith [EMAIL PROTECTED] wrote: On 20.07.2008, at 07:45, Nathan Nobbe wrote: On Sat, Jul 19, 2008 at 4:55 AM, Lars Strojny [EMAIL PROTECTED] wrote: Hi everbody, regarding my mail from yesterday, I've also created an RFC for the new error level. http://wiki.php.net/rfc/e-user-deprecated-warning i definitely like the E_USER_DEPRECATED :D im curious though, about E_DEPRECATED. is this for deprecated functions at the C level, or just the php api? the reason i ask is because deprecation notices are already issued via the E_STRICT level, for example, when using is_a() today, w/ E_STRICT enabled, the following is generated Strict standards: is_a(): Deprecated. Please use the instanceof operator in ... would, perhaps, the deprecation level for is_a() move to E_DEPRECATED (i noticed its still there in 5.3)? deprecation of is_a() was a mistake that has been reverted. thats interesting, may i ask when that would be a better choice that instanceof ? and anyway, there are other examples as well, for example mktime(), PHP Strict standards: mktime(): You should be using the time() function instead in ... would this be another candidate to port to E_DEPRECATED ? so i imagine there will be some work to convert those E_STRICT errors regarding deprecation to the new E_DEPRECATED level. maybe that should go along w/ the patch. as a matter of consistency, i think it would be best to move all E_STRICT errors regarding deprecation to E_DEPRECATED in a single patch, rather than a piecemeal fashion. -nathan
Re: [PHP-DEV] [RFC] E_USER_DEPRECATED
On Sat, Jul 19, 2008 at 4:55 AM, Lars Strojny [EMAIL PROTECTED] wrote: Hi everbody, regarding my mail from yesterday, I've also created an RFC for the new error level. http://wiki.php.net/rfc/e-user-deprecated-warning i definitely like the E_USER_DEPRECATED :D im curious though, about E_DEPRECATED. is this for deprecated functions at the C level, or just the php api? the reason i ask is because deprecation notices are already issued via the E_STRICT level, for example, when using is_a() today, w/ E_STRICT enabled, the following is generated Strict standards: is_a(): Deprecated. Please use the instanceof operator in ... would, perhaps, the deprecation level for is_a() move to E_DEPRECATED (i noticed its still there in 5.3)? -nathan
Re: [PHP-DEV] [PATCH] [RFC] Closures and lambda functions in PHP
On Mon, Jun 16, 2008 at 9:57 PM, Larry Garfield [EMAIL PROTECTED] wrote: Thoughts from a user-land denizen: - Related to that, would it then be possible to add methods to a class at runtime using lambda functions as the added methods? If so, how? If not, is that something that could reasonably be added here without hosing performance (or at least doing so less than stacking __call() and call_user_func_array() does)? im curious about this as well, and i would welcome such functionality. adding methods to class instances from within the definition of the class seems intuitive, the $this keyword should be available, but when adding methods via a variable which holds a handle to a class instance, well, i wonder, would the $this keyword be available within those anonymous function definitions? class Dynamic { private $someVar = 5; /// adding a function to instances from within the class public function addMethodAtRuntime() { $this-dynamicFunc1 = function() { return $this-someVar; // expected to work } } } /// adding a function to an instance externally $dynamic = new Dynamic(); $anotherVar = 6; $dynamic-dynamicFunc2 = function() { lexical $anotherVar; // expected to work return $this-someVar + $anotherVar; // would this work ? } /// invoking dynamically added methods /// (anticipated behavior given above definitions) $dynamic-addMethodAtRuntime(); echo $dynamic-dynamicFunc1(); // 5 echo $dynamic-dynamicFunc2(); // 11 -nathan
[PHP-DEV] documentation on php.net
one of the classes documented on php.net, HttpRequestPool, is not entirely documented correctly. http://www.php.net/manual/en/class.httprequestpool.php as you can see, it is documented as if the class were HttpMessage. who is the correct person / list / w/e to contact w/ such information, so that it can be corrected ? thx, -nathan
Re: [PHP-DEV] Class Properties in Interfaces?
On Tue, May 6, 2008 at 1:21 PM, Lars Strojny [EMAIL PROTECTED] wrote: I think this is too unspecific. At least the visibility, setter and/or getter and type-hint (assuming we will have type hints) should be defined. Otherwise defining properties in interfaces become useless as it does not tell somebody more except there is a property. i agree entirely. -nathan
Re: [PHP-DEV] Class Properties in Interfaces?
On Wed, Apr 30, 2008 at 12:01 AM, Robert Cummings [EMAIL PROTECTED] wrote: On Wed, 2008-04-30 at 01:22 -0400, Nathan Nobbe wrote: On Wed, Apr 30, 2008 at 1:07 AM, Robert Cummings [EMAIL PROTECTED] wrote: We are not talking about data here. We are talking about properties. Data is assigned to a property which is akin to functionality being assigned to a method. A property has all the features of the most simple getter/setter method combination in one fell statement and without the envelope overhead. As such, there is no reason why it could not be part of the interface design. so a 'property' could be any data type? that sounds contradictory to the concept of an interface to me. the only special connotation i have ever encountered for the term 'property' is my *very* brief work w/ vb.net as a teacher. there is a mechanism whereby getters and setters can be declared and a member variable can be named.. then when using instances of the class, client code uses the name of the 'property' which has the same syntax as accessing a public data member, however, the client is transparently being driven through the methods of the 'property'. between SPL ArrayAccess, and magic methods, php already has multiple ways to realize 'properties'. Seriously, are you having this much difficulty understanding that a property is not itself data until such time as it is given a value? If I say something has colour I haven't said what colour, only that it has colour. Red, blue, green, these are data. colour is a property. If I had an interface where I defined the following: ?php Interface Fibre { public $colour; } ? I'm saying that all classes that implement Fibre must have a $colour property. i didn't say what colour. ?php Class Hair implements Fibre { public $colour = null; } $hair = new Hair(); $hair-colour = 'brown'; ? The above is a much less wordy way of doing the following: ?php Interface Fibre { public function setColour( $colour ); public function getColour(); } Class Hair implements Fibre { public $colour = null; public function setColour( $colour ) { $this-colour = $colour; } public function getColour() { return $this-colour; } } $hair = new Hair(); $hair-setColour( 'brown' ); ? Now do you see the equivalence? I don't think I can simplify it anymore. Since they are equivalent your argument is void since it hinges on data. To throw your void argument back at you about a property can be any type so too can a parameter: $hair-setColour( 3.14 ); This is a feature of a dynamic language, not a flaw in my argument. And to beat the dead horse... a parameter declaration isn't data either. so really, all we would get is a group of member variables we know would be there... wow, that seems pretty pointless to me. and in the case of the setter, the client doesnt know about the logic behind the call, so the fact is supplying 3.14 may not result in 3.14 actually getting set. this is why setter methods are import, per my previous statements. i do not consider adding data 'after declaring properties' in interfaces equivalent to supplying an implementation for the method, because php is not strongly typed, therefore no class will ever be able to control what sort of data is set on the properties. that is the entire problem with your proposition. i have to work today, and im sure people are getting sick of my bickering, but truthfully, i would like to know why interfaces were added to php in the first place? where, if any place, did they take inspiration from, java, c++, neither ? i only ask because im dying to know and we're on the topic.. -nathan
Re: [PHP-DEV] Class Properties in Interfaces?
On Wed, Apr 30, 2008 at 9:55 AM, Robert Cummings [EMAIL PROTECTED] wrote: On Wed, 2008-04-30 at 09:39 -0600, Nathan Nobbe wrote: so really, all we would get is a group of member variables we know would be there... No, you know nothing about the existence of properties when using getters and setters. Just because you have getColour() and setColour() in no way implies you have $this-colour right, thats exactly it, the client doesnt know anything about the data. it is being driven through a well-defined interface whereby the client has no control but to ask the provider to do something for it. wow, that seems pretty pointless to me. It would seem it does. Wrapping all my properties in redundant getter/setter methods often seems pointless to me and a whole slew of other people. so put the public properties on classes that implement interfaces. as i said, getters and setters on an interfaces make little sense, since implementors are assumed to provide different implementations. and in the case of the setter, the client doesnt know about the logic behind the call, so the fact is supplying 3.14 may not result in 3.14 actually getting set. You're presuming logic. I'm not. I just want to get/set the property without invoking a function call. If properties didn't have their uses, then you wouldn't be able to access them from the object. Since I'm not forced to use a getter/setter method, then it follows that properties were designed to be accessed and not necessarily wrapped in a method for retrieval and setting. i understand your point. but just because the public access level exists, doesnt mean it was intended that member variables be assigned that level of access either. convention is to mark member variables protected or private, and drive access through a public well-defined *interface*. i have read at least a dozen books, ranging from various languages and topics and never have i heard of properties constituting part of the interface. indeed this would be an entirely new concept after generations that have arrived at the conclusion that an interface is a set of methods signatures. this is why setter methods are import, per my previous statements. Important for some. You once again, with all your hand flapping, assume we want some kind of operation on the data. If we do not, and this happens a lot, then we're just wasting cycles... and order of magnitude more cycles. you are currently free to place public properties on any class or abstract class you wish. imho, that is entirely adequate. what i can say however, is that allowing such a feature forces designers and groups of developers to fall back on convention. that deviates from the entire purpose of interfaces. interfaces are about control; you must adhere to this contract. since php is loosely typed, the only way to maintain the 'intended' use of these properties would mean rigorous checking by developers of the code at design time. im not saying this is impossible, or something *some* people wouldnt be happy to do, in light of the performance gains. but the fact remains, the only thing that could maintain the integrity of the public properties would be rigorously maintained conventions. i do not consider adding data 'after declaring properties' in interfaces equivalent to supplying an implementation for the method, because php is not strongly typed, therefore no class will ever be able to control what sort of data is set on the properties. that is the entire problem with your proposition. Ummm, this functionality already exists. Your argument neglects to consider that objects already exist where the properties can be directly accessed and set. Your argument assumes a need to manage the data being assigned. Your argument assumes the data wasn't already managed by the assigner of the data. You assume a lot, and yet we all know in practice there are many, many, MANY implementations of classes where the properties are directly exposed. This may not be something YOU like, but it is what many others like. Some people still care about efficient code versus the flexibility of meeting a demand that may never arise. this much you are right about. i have to work today, and im sure people are getting sick of my bickering, but truthfully, i would like to know why interfaces were added to php in the first place? where, if any place, did they take inspiration from, java, c++, neither ? i only ask because im dying to know and we're on the topic.. Create a new thread. You rider question isn't relevant to this thread. fine. -nathan
[PHP-DEV] why interfaces ?
all, in recent weeks there has been a lot of arguing about what interfaces are, arent (on php-general and now on the internals list as well) etc. etc. i am quite curious, why interfaces were added to the language in the first place. note, i am not criticizing them, i am overjoyed that the language has them, however i am curious about the history. is this something php borrowed from java? does it have anything to do with 'entirely virtual classes' in c++ ? i think that the history behind the addition of interfaces to php, would shed a lot of light on their intended purpose for use by php developers. thanks, -nathan
Re: Re: [PHP-DEV] Class Properties in Interfaces?
On Tue, Apr 29, 2008 at 6:28 AM, John Carter -X (johncart - PolicyApp Ltd at Cisco) [EMAIL PROTECTED] wrote: I think I must be missing something here, but this sounds a little tautological - we can't do it because it doesn't make sense. This is because it doesn't make sense Certainly most people (myself included) consider interfaces to be methods only, but I can't find a reason why not, and a search-on-wikipedia-instead-of-doing-proper-research appears to allow it: http://en.wikipedia.org/wiki/Interface_%28computer_science%29 the problem with that article, as it pertains to this conversation is that it is referring to interfaces as a general concept. 'interfaces' can be formed in many ways, via extension of an abstract class or even an expected set of a parameters in an HTTP request... getting to the more concrete term 'interface' as it pertains to a language keyword, interfaces define a contract; they do not specify implementation details. member variables only facilitate the actions member functions expose and therefore, they are part of the implementation. additionally, one can look to java (and likely others) to see that public attributes are not supported on interfaces. here is a definition from a java5 cert book; When you create an interface, you're defining a contract for *what* a class can do, without saying anything about how the class will do it. An interface is a contract. -nathan
Re: Re: [PHP-DEV] Class Properties in Interfaces?
On Tue, Apr 29, 2008 at 9:51 AM, John Carter -X (johncart - PolicyApp Ltd at Cisco) [EMAIL PROTECTED] wrote: The article explicitly mentions OOP interfaces in a few languages. my bad. But the article, or for that matter any formal definition of an interface isn't really what I asked about: My question was simply: why can't interfaces have properties? when you say properties, do you mean a particular set of methods map to a particular instance variable, as getters and setters (i saw that definition from Sebastian earlier)? if thats the case than interfaces cant have properties because they require instance variables. -nathan
Re: Re: [PHP-DEV] Class Properties in Interfaces?
On Tue, Apr 29, 2008 at 10:28 AM, John Carter -X (johncart - PolicyApp Ltd at Cisco) [EMAIL PROTECTED] wrote: Nathan, By example: interface EggLayer { public $eggsLaid; } class Chicken implements EggLayer; Some would say (and maybe I would too) that you should have a getEggsLaid() method, that's fair enough. But why not the above? because, from above, $eggsLaid constitutes the implementation of any class that implements EggLayer. You say interfaces can't have properties because they require instance variables. thats fine, in fact thats what i take the two terms to mean; however, there was an alternate definition given in an earlier post and i just wanted to clarify whether you were referring to that definition of property. hence forth i understand that you are not referring to that definition. Why do they require instance variables? this was only based on the aforementioned definition of properties whereby a property is an instance variable that has respective getters and setters. in the absence of that definition, my statement is irrelevant. I also think for the purposes of this discussion, property and instance variable mean the same thing. cool, then i would say that interfaces cannot have public properties in them because it imposes implementation requirements on any implementors. to specify implementation details, there is the abstract class. -nathan
Re: [PHP-DEV] Class Properties in Interfaces?
On Tue, Apr 29, 2008 at 6:14 PM, Richard Quadling [EMAIL PROTECTED] wrote: 2008/4/30 Robert Cummings [EMAIL PROTECTED]: On Tue, 2008-04-29 at 20:04 +0200, John Carter -X (johncart - PolicyApp Ltd at Cisco) wrote: I think there's been two responses to this query: 1. We can't have properties in interfaces because interfaces don't have properties. I would say this is tautological and doesn't add anything. 2. Why would you need to? Getters and setters work. So I suppose to answer my question for myself, there's no real technical reason for not having properties in interfaces, but getters and setters work just fine and no-one (including me) really misses them. I have to agree. Enforcing existence of a property is just as much part of an interface as enforcing the existence of a method. Why go down the clutzy getter and setter method route when properties were meant to be accessed. Why should code be made slower? Methods are at least an order of magnitude slower than direct property access. Cheers, Rob. -- http://www.interjinn.com Application and Templating Framework for PHP There are some advantages. 1 - Read only / write only properties can be created more obviously, rather than having the logic spread thoughout the __magic_functions. 2 - Automatic document tools get a real benefit from having a defined mechanism to work from. not only that, but the only recourse to add logic to access of previously declared public variables without changing the interface is to resort to magic methods. up front, using public member variables may be enticing, there are less instance methods and access is faster, sure. but when, down the road, some logic is required around access, and the only recourse is to employ a magic method, what would be slower then? the magic method doing runtime introspection on the class instance prior to invoking said logic, or having a purpose built method(s) there in the first place? obviously the later; and that is just one more reason why getters and setters, coupled with hidden member variables, make sense, even in php. -nathan
Re: [PHP-DEV] Class Properties in Interfaces?
On Tue, Apr 29, 2008 at 9:22 PM, Robert Cummings [EMAIL PROTECTED] wrote: On Tue, 2008-04-29 at 19:01 -0600, Nathan Nobbe wrote: On Tue, Apr 29, 2008 at 6:14 PM, Richard Quadling [EMAIL PROTECTED] wrote: 2008/4/30 Robert Cummings [EMAIL PROTECTED]: On Tue, 2008-04-29 at 20:04 +0200, John Carter -X (johncart - PolicyApp Ltd at Cisco) wrote: I think there's been two responses to this query: 1. We can't have properties in interfaces because interfaces don't have properties. I would say this is tautological and doesn't add anything. 2. Why would you need to? Getters and setters work. So I suppose to answer my question for myself, there's no real technical reason for not having properties in interfaces, but getters and setters work just fine and no-one (including me) really misses them. I have to agree. Enforcing existence of a property is just as much part of an interface as enforcing the existence of a method. Why go down the clutzy getter and setter method route when properties were meant to be accessed. Why should code be made slower? Methods are at least an order of magnitude slower than direct property access. Cheers, Rob. -- http://www.interjinn.com Application and Templating Framework for PHP There are some advantages. 1 - Read only / write only properties can be created more obviously, rather than having the logic spread thoughout the __magic_functions. 2 - Automatic document tools get a real benefit from having a defined mechanism to work from. not only that, but the only recourse to add logic to access of previously declared public variables without changing the interface is to resort to magic methods. up front, using public member variables may be enticing, there are less instance methods and access is faster, sure. but when, down the road, some logic is required around access, and the only recourse is to employ a magic method, what would be slower then? the magic method doing runtime introspection on the class instance prior to invoking said logic, or having a purpose built method(s) there in the first place? obviously the later; and that is just one more reason why getters and setters, coupled with hidden member variables, make sense, even in php. That should be a matter of choice for the developer. When you say but when, down the road, some logic..., all I see is you waving your hands in the air and presuming that the logic will change. The logic may not change, in which case why am I incurring the cost of getter/setter methods. If the logic changes, I'll be happy to add getter and setter methods at that time and punt the needed functionality into the magic methods which will call the appropriate getter or setter method. You are preparing for a future that may not come, I am willing to retroactively handle that future if it arrives. Neither approach strikes me as being more correct but rather they each presume an educated guess on the likelihood of the property changing it's semantics down the road. the developer does have a choice. to use an interface, or an abstract class. data facilitates methods accomplishing what it is they purport. quite frankly, i have never written an interface with getters and / or setters anyway, nor do i see the need to. i would consider it silly. interfaces are typically used to say, any class that makes this happen will likely do it in a way differently than all the others. since, getters and setters are almost always implemented the exact same way i find these topics to be rather different. if there is in fact a standard way of doing things for any given interface, then to realize it, a common implementor class can be composed, and delegated to by classes that implement said interface in the 'standard' way. -nathan
Re: [PHP-DEV] Class Properties in Interfaces?
On Wed, Apr 30, 2008 at 12:05 AM, Robert Cummings [EMAIL PROTECTED] wrote: On Tue, 2008-04-29 at 23:51 -0400, Nathan Nobbe wrote: On Tue, Apr 29, 2008 at 9:22 PM, Robert Cummings [EMAIL PROTECTED] wrote: That should be a matter of choice for the developer. When you say but when, down the road, some logic..., all I see is you waving your hands in the air and presuming that the logic will change. The logic may not change, in which case why am I incurring the cost of getter/setter methods. If the logic changes, I'll be happy to add getter and setter methods at that time and punt the needed functionality into the magic methods which will call the appropriate getter or setter method. You are preparing for a future that may not come, I am willing to retroactively handle that future if it arrives. Neither approach strikes me as being more correct but rather they each presume an educated guess on the likelihood of the property changing it's semantics down the road. the developer does have a choice. to use an interface, or an abstract class. data facilitates methods accomplishing what it is they purport. quite frankly, i have never written an interface with getters and / or setters anyway, nor do i see the need to. i would consider it silly. interfaces are typically used to say, any class that makes this happen will likely do it in a way differently than all the others. since, getters and setters are almost always implemented the exact same way i find these topics to be rather different. if there is in fact a standard way of doing things for any given interface, then to realize it, a common implementor class can be composed, and delegated to by classes that implement said interface in the 'standard' way. Abstract classes and interfaces are not the same. They are used for fundamentally different reasons. An interface is to enforce a contract for all implementations of the interface. Therefore if I were to create an interface with an interface property of x, then all implementations using that interface would know that property x exists and could use it thusly without having to check for it's existence. i am fully aware of the differences between interfaces and abstract classes. however, if a public method is defined on any class, abstract or concrete, it may be used without checking by client code; i believe thats the entire point.. Using an abstractclass is a hack, it's not sufficient for enforcement, and you can't combine multiple abstract classes as you can with interfaces. abstract classes have their place. primarily they are well suited for template method because some methods can be forced to be implemented by children and others can be optionally overridden. and lastly, coming to multiple inheritance (for lack of better terminology); that is the only argument with any value for adding public attributes to the interface construct; however i am still not receptive to it. from my perspective data is an implementation detail, period. -nathan
Re: [PHP-DEV] Class Properties in Interfaces?
On Wed, Apr 30, 2008 at 1:07 AM, Robert Cummings [EMAIL PROTECTED] wrote: On Wed, 2008-04-30 at 00:27 -0400, Nathan Nobbe wrote: On Wed, Apr 30, 2008 at 12:05 AM, Robert Cummings Abstract classes and interfaces are not the same. They are used for fundamentally different reasons. An interface is to enforce a contract for all implementations of the interface. Therefore if I were to create an interface with an interface property of x, then all implementations using that interface would know that property x exists and could use it thusly without having to check for it's existence. i am fully aware of the differences between interfaces and abstract classes. however, if a public method is defined on any class, abstract or concrete, it may be used without checking by client code; i believe thats the entire point.. Using an abstractclass is a hack, it's not sufficient for enforcement, and you can't combine multiple abstract classes as you can with interfaces. abstract classes have their place. primarily they are well suited for template method because some methods can be forced to be implemented by children and others can be optionally overridden. and lastly, coming to multiple inheritance (for lack of better terminology); that is the only argument with any value for adding public attributes to the interface construct; however i am still not receptive to it. from my perspective data is an implementation detail, period. We are not talking about data here. We are talking about properties. Data is assigned to a property which is akin to functionality being assigned to a method. A property has all the features of the most simple getter/setter method combination in one fell statement and without the envelope overhead. As such, there is no reason why it could not be part of the interface design. so a 'property' could be any data type? that sounds contradictory to the concept of an interface to me. the only special connotation i have ever encountered for the term 'property' is my *very* brief work w/ vb.net as a teacher. there is a mechanism whereby getters and setters can be declared and a member variable can be named.. then when using instances of the class, client code uses the name of the 'property' which has the same syntax as accessing a public data member, however, the client is transparently being driven through the methods of the 'property'. between SPL ArrayAccess, and magic methods, php already has multiple ways to realize 'properties'. -nathan
Re: [PHP-DEV] Help with calling PHP functions
On Sat, Apr 26, 2008 at 2:23 PM, Dhiru Pandey [EMAIL PROTECTED] wrote: [My apologies if I am posting on the wrong group...please point me to the right one] I am trying to figure out a way to invoke PHP functions directly i.e. bypassing the PHP compiler (scanner and parser). For now it would be great if I can get some help calling them from C. Ultimately I would like to call them from Java. per calling them from java you might use or investigate the quercus or 'ibm project 0' projects. they might not be what you want as they are separate java-based implementations of php, but im guessing you can access php through them; or at any rate the java equivalent, but they dont really say that explicitly. http://www.caucho.com/resin-3.0/quercus/#Java-Users -nathan
Re: [PHP-DEV] Return type hinting patch
On Sat, Apr 26, 2008 at 2:06 PM, David Zülke [EMAIL PROTECTED] wrote: Wouldn't the most consistent way be to omit function altogether when using a return type hint? public static function zomg() { return $somethingArbitrary; } public static string foo() { return $mustBeString; } i think leaving 'function' in there makes sense because thats the way php currently works. otoh, should there ever be a type function (e.g. for anonymous funcs) down the road, that'd mean trouble ;) wow; good point! maybe if anonymous functions are ever supported the type could be capitalized as in 'Function' public function Function doStuff() { return function() {} } -nathan
[PHP-DEV] issues with classnames, staic class members and constants as variables
hello all, this is my maiden voyage on the internals list. recently i have discovered functionality that existed in php-5.2.4 that missing in php-5.2.5 and also php-5.2.6_rc3. i have posted to the php-general list and to the php-qa list and not received any sort of feedback about this discovery. primarily, in php-5.2.4 variables could be used to hold the name of a class and used to access static members (both attributes and methods) as well as constants. there was other related support as well. please see the archived post on the qa list for details, http://marc.info/?l=php-qam=120901795414161w=2 there you will see i have prepared phpt tests and run them on php-5.2.4 and php-5.2.6_rc3 installs. im curious if support was intentionally removed or if it was an oversight? if so, is this something that could be forward ported from php-5.2.4? i would be willing to work on a patch if that were the case. thanks, -nathan
Re: [PHP-DEV] issues with classnames, staic class members and constants as variables
On Fri, Apr 25, 2008 at 10:44 AM, Etienne Kneuss [EMAIL PROTECTED] wrote: Hello, Are you using a custom and outdated build of 5.2.4 ? $classname::$member was introduced in php5.2.4 but removed before the actual release, and is now only present as of PHP5.3. thanks for your reply. apparently i am; looking in my portage directory i can see: php-5.2.4.ebuild php-5.2.4_pre200708051230-r2.ebuild and the build i have installed is the latter. do you know why this was removed prior to 5.3; just curious.. -nathan
Re: [PHP-DEV] issues with classnames, staic class members and constants as variables
On Fri, Apr 25, 2008 at 12:52 PM, Etienne Kneuss [EMAIL PROTECTED] wrote: Sure: as I said earlier, it was proposed to be included already in 5.2.4, but some people objected as it represented too much of a language change which should not happen in minor release. So even though the patch impact was minimal, it was postponed and thus only committed in the 5_3 branch. fair enough i suppose. thanks for filling me in. -nathan
Re: [PHP-DEV] Return type hinting patch
On Fri, Apr 25, 2008 at 1:15 PM, Sam Barrow [EMAIL PROTECTED] wrote: On Fri, 2008-04-25 at 14:08 -0500, Jeremy Privett wrote: Sam Barrow wrote: I figured it out, the syntax is now as follows: function a($b, $c) returns d { } I'll post an update soon. That's certainly a non-intuitive syntax. How about we take a page out of the book of other C-style languages before trying to invent something else? I agree with Stas, return and returns are not part of a function definition. I don't think it's non-intuitive at all, and even so, it's the most intuitive we have. This ordering makes more sense to me at first glance (in the order I would think about things; scope, name, arguments, return). im not sure the following has been explicitly proposed, but how about omitting the 'return' keyword and placing the return type hint before the function identifier function int a($b, $c) {} i think that is most congruent with 'typical' of c style languages, no ? -nathan