Re: [PHP-DEV] [RFC] Reclassifying engine warnings
> From: Aegir Leet > Either way, if you want a less strict language, that language already > exists: It's the current version of PHP and you and everyone else who > likes the way it works can keep using it. For approximately 3 years. Please remember "end of life". We'd still be using php5 today if it weren't for "end of life". I interpret the above paragraph as a request to split between p++ and php classic. I'd be fine with that and use php classic, but I believe the idea of splitting failed by a very wide margin. - Todd
Re: [PHP-DEV] [RFC] Reclassifying engine warnings
> If we want PHP to be as easy as possible then $nullref->bar(), > $foo->someUndefined(), > new UndefinedClass etc shouldn’t be exceptions either - they can just be > notices. That's very different. Note that this code doesn't even generate a notice: $x = null; var_dump($x+1); I'm joining the thread to point out another way to avoid the notice in hopes that this way doesn't get deprecated or somesuch: $temp =& $never_defined; // No notice :) $temp++; // Happily becomes 1 if $never_defined wasn't defined unset($temp); // so we don't unintentionally make more changes with $temp later Our code predates "??" and we use the above boilerplate in many, many places, but it isn't boilerplate enough to easily search and replace. - Todd > On Aug 28, 2019, at 4:01 PM, Stanislav Malyshev wrote: > > Hi! > >> Javascript has treated undefined variables as a catchable exceptions since >> (I think?) forever. > > Which seems to be why I open a random Javascript file in our codebase > and see this: > > var wikibase = wikibase || {}; > wikibase.queryService = wikibase.queryService || {}; > wikibase.queryService.ui = wikibase.queryService.ui || {}; > wikibase.queryService.ui.toolbar = wikibase.queryService.toolbar || {}; > > wikibase.queryService.ui.toolbar.Actionbar = ... > > (not my code but I've seen it a lot) > IMHO, this is language getting in a way and people writing boilerplate > to avoid "service" that is not actually needed. > >> much work. This means its developers often don't improve much either, which > > I don't think PHP should be a language that "builds character" by > forcing people to do more work than it's necessary for them, in order > for them to "improve". I think it should be as easy as possible, and if > somebody wants to learn how the bits move, one can always pick up a good > book or go to a Coursera course, etc. > > -- > Stas Malyshev > smalys...@gmail.com -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Re: Bringing Peace to the Galaxy
> ... > 3. Putting your apparent personal bias against backwards compatibility > aside - if P++ goes in the directions you're hoping for - towards giving > you the goodies on your wish list, why would you care if PHP still existed > without these new changes/features? > > Zeev I just want to express a personal bias - joy at reading the proposal. Our php code goes back to approx 2002. We did get a performance improvement moving to PHP7 and it has allowed us to integrate with third party modules that were not compatible with PHP5, but it also required many, many hours that were not spent moving our application forward in other ways. I think the #1 reason for changing PHP versions for us is security policy. If a PHP version is "end of life" we must move on, no matter how much pain it causes and how perfectly acceptably everything was functionally running on the older version. The idea of having code that works be allowed to continue to work is very, very appealing. I don't want people who want to go in bold new directions to be held back; the proposal seems like something that would help me sleep more peacefully while allowing the adventurous to proceed. Thanks! - Todd (usually quiet here)
Re: [PHP-DEV] [RFC] Basic Scalar Types
On Sat, 2015-03-14 at 00:22 +0100, Bob Weinand wrote: Am 14.03.2015 um 00:14 schrieb Zeev Suraski z...@zend.com: -Original Message- From: Bob Weinand [mailto:bobw...@hotmail.com] Sent: Saturday, March 14, 2015 1:07 AM To: PHP Internals List Cc: Zeev Suraski; guilhermebla...@gmail.com Subject: Re: [PHP-DEV] [RFC] Basic Scalar Types I won't go into vote tomorrow. Given that we already discussed that proposal a lot a few months ago (Andreas v1), we can go for a discussion phase a bit shorter (like 10 days total), but I won't put a new RFC into vote tomorrow. Especially as it's still being heavily discussed. Also, this vote is just valid in case where other votes fail - so we actually don't *compete* with Anthonys RFC. It doesn't affect the voting period of Anthonys RFC. We can have the vote still going on a few days after both RFCs failed. This RFC is only about the common part of both RFCs. Bob, If you don't put it into a vote by Sunday, then by definition it can't get into v7.0 - unless we either have another vote to delay the timeline (big hassle). Plus, as you can see, there are people (heck, even me) that would vote in favor of the Dual Mode RFC just because there's no alternative. Zeev Zeev, If I put it into vote until Sunday, we're breaking the voting process. Which required an apt discussion phase which definitely isn't given when we start Sunday. Also. Your timeline RFC leaves a bit room for interpretation (Line up means? Put into discussion? Vote? Have votes all already accepted?) . If necessary, I'll rather push timeline a bit than breaking vote process. Thanks, Bob If people (including Zeev) would not vote for Anthony's RFC knowing that Bob's RFC will be put to a vote later, but would vote for Anthony's RFC without Bob's RFC coming next, it sounds like Bob's RFC competes with Anthony's RFC. This whole thing is depressing. I am confident Zeev means well, but as a usually silent watcher of this list, I'll give this bystander's view of the recent discussion: I don't like X, but I'll vote for it unless I can get Y approved. I can't get Y approved, but I don't want to vote for X; How about Z? I know some people consider Z to be common ground because it is a sort of intersection of X and Y, but it is clear that is not a consensus. It's a little odd for me to write this email because I am someone who personally isn't interested in strict typing at all, but the political games make me sad, so I felt I needed to comment. I try not to write often, so I'll throw in an off topic comment here: Thanks, Stas! I've seen you write many common sense emails responding to proposals that would make life harder for long time users without bringing significant benefits. (Thanks to Lester for doing so also, but somehow I expect it from Lester and appreciate it more from Stas. Thanks to you both.) - Todd -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Remove PHP 4 Constructors
On Sat, 2015-01-17 at 10:56 -0700, Levi Morrison wrote: We are talking about something deprecated since 10 years, about the 1st major release in a decade, something we will use for the next 12-14 years. That is the point - PHP 4 constructors have NOT been marked as deprecated in the manual, and they produce no warnings at runtime. If they have not been marked as deprecated then you cannot suddenly remove them. Warning: a long response with code snippets/ [ Snipped examples of mixing constructor flavors / namespaces ] Then there are no warnings of any kind (since PHP 5.3.2), and __construct is used as the constructor. The method test is just a normal method. To me this clearly indicates three things: 1. Having both forms of constructors is bad form (hence the E_STRICT) 2. When both are present the new-style __construct is used over the old-style PHP 4 constructor, meaning the language prefers __constructor. 3. Old-style constructors don't exist in namespaces. Notably this was a conscious choice as evidenced by behavior that existed in PHP 5.3.0 - 5.3.2 where the E_STRICT was emitted like non-namespaced code. This is the behavior of shipped, stable versions of PHP. I think it's a bit illogical to conclude that just because there aren't any E_DEPRECATED warnings emitted in PHP 5 that old-style constructors are fully supported. That leaves us realistically with four options: 1. Bring full support for PHP 4 constructors 2. Emit E_DEPRECATED when PHP 4 constructors are used 3. Drop support for PHP 4 constructors so they are just normal methods, just as they are in namespaces 4. Maintain current behavior. As already mentioned I think as an end result we shouldn't have two ways to define constructors. Given that PHP already prefers the new-style constructors I've proposed that we work towards dropping the old-style, it's just down to a matter of how. I've been following these threads for about 10 years and beg that php internals continues to live and let live. There have been many, many threads over the years from what I would call (with obvious bias) OO fundamentalists. They seem to be at war with code that is bad form. Fortunately, most of their victories to date have been in the form of adding E_STRICTs. There seems to be a compromise in the community that we won't break people's code, but we'll let them know when they are using bad form code. I believe that's reasonable. Please don't construe the willingness to add E_STRICTs with agreement that such code should be forcibly eliminated. If there were a fully automated tool to bring code into compliance, I would feel a lot better about such changes, but even then, many of us would be applying that tool to third-party code that has been lying around for a decade untouched, and that's scary. I suppose my opinion on these things is formed by my life experience with these issues and since I don't doubt we all mean well, I guess the OO purists probably are approaching this from different life experiences. Here is where I'm coming from: I've been on my current project for over 10 years. We have always had a _very_ small software department. The code was originally developed in php4 style using using objects, but not following the purist OO conventions. We now have hundreds of thousands of lines of php. We've accumulated reliance on many libraries that were written in a variety of styles and generally we're just glad they work. I'm sure there is no active development on many (perhaps most) of them. To this day, we still don't use namespaces or exceptions. We still follow our conventions for prefixing everything to avoid name collisions. We don't have the resources to make major changes without clear benefits to our users. (For the record, when we do find an issue with php, we dig in and try to find a fix and submit it. We've fixed a couple of things. I know it is negligible compared to what most of the folks reading this do.) I don't know how common our situation is, but I'm sure there are others out there. In the global cost/benefit analysis I don't see that the benefits of purifying OO outweigh the costs. Thanks for listening! - Todd -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
[PHP-DEV] Uniform Variable Syntax
On 8 Jul 2014, at 15:48, Derick Rethans der...@php.net wrote: I've just voted no for this, because it introduces a tiny BC break. Now, I realize this is a tiny BC break, but it is just *those* that drive people nuts when upgrading. There is so much non-public code - a cursor check of Symfony and ZF is not representative. From Andrea Faulds: It is a tiny BC break and it’s for PHP NEXT (i.e 6 or 7), not 5.6. Why not? It’s a tiny change which will bother some people but make everyone else’s life easier. Thank you, Derick, for voting against a BC break. I do appreciate the intention of making things more consistent. Given that this is a parser change, I wonder if there is hope of mitigating the BC issues by providing an option to generate new code from old code. Today, I can run php -l and php will tell me about syntax problems. If php6 had a php --convert-from 5.4.30 that would read in a file that worked in 5.4.30 and output a file that does the same thing using php6 syntax, I think that would be a Good Thing. Perhaps it would be better as a tool on the side than as part of the main php executable. I know such a conversion process is effectively impossible for some BC breaks; I don't know about this one. This RFC struck me as a better candidate than usual. Thanks for your consideration. - Todd -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
[PHP-DEV] Re: Deprecate and remove calls from incompatible context
Some of us have rather large bodies of code written over 10-12 years that make significant use of calling $this from incompatible contexts (i.e. we know it's compatible, but php doesn't). Most consider such use a sin. Could there be a compromise that would allow us evildoers to continue in our evil ways without identifying and changing every use? Perhaps implements allowStaticCallsFromIncompatibleContexts or somesuch? I can imagine replacing every class ... with class ... implements ..., but identifying and changing every place we use an incompatible context will be very, very unpleasant. We can figure out the places that are hit most frequently using the logs, but that isn't necessarily a complete list. If this were a security issue, I'd understand making everyone go through the pain. The RFC indicates the rationale is helping users find bugs. It would be nice if those of us who would rather avoid a BC break than easily find those bugs could do so. Thanks for your consideration. - Todd -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Remove calls with incompatible Context
On Mon, 2012-07-30 at 19:31 +0200, Gustavo Lopes wrote: https://wiki.php.net/rfc/incompat_ctx An RFC for deprecating and removing $this from incompatible context. Comments are welcome. -- Gustavo Lopes I'm just a user, but I'd like to beg that the feature not be removed, at least not without having an ini setting for at least a couple of years. As the RFC states, This feature can, however, be used to implement trait-like behavior, and I'm sure someone somewhere did such a thing. I know in our company's code, such uses were frequent. I believe they are still common. Refactoring often doesn't fit the schedule. I doubt we're unusual in allowing classes to do more than they should instead of separating code off into a trait or making other high level changes. Note that traits have only been available since March 1, 2012 (php 5.4.0). I don't think axing register globals is very relevant. Perhaps after traits have been available for several years the comparison would be better. With register globals, a good alternative (the $_ variables) have been around for many years. With traits, a good alternative has been around for a few months. I think the point of mentioning register globals is just to say We've made huge BC breaks before. That doesn't make it less painful. Off-topic, but to show a potentially higher priority... If you want to get rid of class related WTF, please put get_class() back to the way it used to be. Right now, calling get_class() with a variable that is null is the same as calling get_class with no arguments. I can imagine why that might be convenient for the implementation, but it is terribly confusing. Thanks for listening. - Todd -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
[PHP-DEV] Was php bug (IMHO). Have fix. Re: Bad eval() leading to response code 500
eval() does indeed set the response code to 500 upon failure. Is that a bug? I'll file a report because I don't believe leaving the response code at 500 is consistent with the statement from the php.net page about eval(): If there is a parse error in the evaluated code, eval() returns FALSE and execution of the following code continues normally. I don't think leaving the the response code at 500 is consistent with continues normally. I believe the fix is one line, adding EG(current_execute_data)-opline-extended_value != ZEND_EVAL to the if clauses before setting the error header in main.c at line 1132. In case anyone finds my post from last night while doing a search of the archives, I'll explain more below and answer my question about debugging. What I didn't realize at the time of my post last night is that browsers don't mind receiving a 500 as long as everything else looks good. For example, the following web page: ?php eval('0+'); print hello world\n; ? looks fine in a browser so I assumed (oops!) that it was returning code 200. If you try doing a wget on that example, it complains about the response code 500. (My big ugly application uses AJAX and the 500 caused my AJAX framework to reject the page.) Other than the code 500, everything seems to proceed normally. All of the other code is executed normally. The content of the web page is normal and is displayed well in a browser unless you have something checking for unhappy response codes. The answer to my question about watching the headers in the debugger turned out to be pretty easy: watch sapi_globals.sapi_headers watch sapi_globals.sapi_headers.http_response_code It would not have been so simple with ZTS on. (In that case, the TSRM macros come in to play.) -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
[PHP-DEV] Bad eval() leading to response code 500
It feels like there is a bug in php somewhere. I'm trying to debug this myself before filing a report and am in over my head. The short version of my question may be How do I set a watch on SG(sapi_headers).http_response_code in the gdb? I think I need to debug it myself because I haven't been able to reproduce it in a simple case. The following simple case works: ?php // In the real application there is a lot of code before this. $x = eval('$y=0+;'); if ($x === false) { $x = 'Unknown'; } // In the real application there is a lot of code between the // above and the below. print x is $x\n; ? That always gives success. In my big ugly application, I get a response code 500 if the eval is given poorly formed code. The exact same request is processed happily if the eval of poorly formed code is commented out or replaced with an eval of good code. The poorly formed code can be as simple as the above example ('$y=0+;'). I've rebuilt apache 1.3.37 so that I can use gdb. (I'm using php 5.4.3) After about 10 hours I've only gotten as far as learning that r-status becomes 500 while the headers are being prepared at the time of the print. That happens in mod_php5.c on line 231: r-status = SG(sapi_headers).http_response_code; I guess my next step is to find out when SG(sapi_headers).http_response_code became 500. Given that the problem appears/goes away based on whether the eval is given bad code, I'm guessing the response_code is being affected by the eval(), but I'd like to be more concrete about it and maybe even be able to come up with a fix (or at least a good enough description that someone who really understands internals can come up with a fix without much trouble). Perhaps I've completely misunderstood something about php and should be directing this to a different list. My confidence is high that a bad eval() shouldn't ruin the page, so I'm here looking for debugging advice. If I'm in the wrong place, I apologize. Thanks for any pointers! - Todd -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
[PHP-DEV] Re: Bad eval() leading to response code 500
[I'm afraid of getting flamed for how bad the code was in the example in my first email. I've replaced the example in this email. The rest is the same. The example still isn't great, but it's better than before.] It feels like there is a bug in php somewhere. I'm trying to debug this myself before filing a report and am in over my head. The short version of my question may be How do I set a watch on SG(sapi_headers).http_response_code in the gdb? I think I need to debug it myself because I haven't been able to reproduce it in a simple case. The following simple case works: ?php function f($processed_string) { // eval returns false on failure (e.g. division by 0) $eval_result = @eval('$retval=('.$processed_string.');'); if ($eval_result === false) { return 'Unknown'; } return $retval; } print f('0+5').\n; // Good print f('0(6)').\n; // Bad, but shouldn't lead to code 500 print f('0+').\n; // Bad, but shouldn't lead to code 500 ? That example doesn't return code 500. But my big ugly application does. I get a response code 500 if the eval is given poorly formed code. The exact same request is processed happily if the eval of poorly formed code is commented out or replaced with an eval of good code. The poorly formed code can be as simple as in the above example. I've rebuilt apache 1.3.37 so that I can use gdb. (I'm using php 5.4.3) After about 10 hours I've only gotten as far as learning that r-status becomes 500 while the headers are being prepared at the time of the print. That happens in mod_php5.c on line 231: r-status = SG(sapi_headers).http_response_code; I guess my next step is to find out when SG(sapi_headers).http_response_code became 500. Given that the problem appears/goes away based on whether the eval is given bad code, I'm guessing the response_code is being affected by the eval(), but I'd like to be more concrete about it and maybe even be able to come up with a fix (or at least a good enough description that someone who really understands internals can come up with a fix without much trouble). Perhaps I've completely misunderstood something about php and should be directing this to a different list. My confidence is high that a bad eval() shouldn't ruin the page, so I'm here looking for debugging advice. If I'm in the wrong place, I apologize. Thanks for any pointers! - Todd -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
[PHP-DEV] get_class
$x = null; get_class($x) returns get_class($this) as of 5.3. I don't recall seeing a discussion of this on the list and I can't find anything about this change in the archives. The documentation is currently self-contradictory... Under Return Values: Returns the name of the class of which object is an instance. Returns FALSE if object is not an object. Under Changelog: Since 5.3.0 NULL became the default value for object, so passing NULL to object now has the same result as not passing any value. (BTW, I don't see that listed in http://us.php.net/ChangeLog-5.php#5.3.0 ) I guess there hasn't been a lot of screaming about it, so maybe it isn't a big deal, but it seems like a significant BC break to me. Maybe it's just because I've been beating my head against a wall for so long trying to figure out why my code was behaving so strangely. ;) I can't believe it's impossible to differentiate between receiving an argument and not receiving an argument. Would anyone really intentionally pass a null to this function to get the result of get_class($this)? Now that I know about this BC break, I'm OK and can avoid the issue, but for the sake of the next person to hit this, I felt I should post on the topic. I almost posted a bug directly, but the behavior is documented, so I thought this would be the correct place. - Todd -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
[PHP-DEV] Re: foreach() for strings
Adding to John Crenshaw's list of reasons not to implicitly treat strings as arrays in foreach loops... Please keep in mind the following valid code: $s = 'hello'; foreach ((array)$s as $x) { var_dump($x); } The result is: string(5) hello That behavior can be handy. Hopefully, a BC break wouldn't occur if any of the string features currently being discussed are implemented. Without a BC break, having strings implicitly be treated as arrays in foreach loops will seem very strange in cases like the above. Iterators are nice. Having a text_string_to_array function would also be fine. For example: $s = 'hello'; foreach (text_string_to_array($s) as $x) { var_dump($x); } The result would be: string(1) h string(1) e string(1) l string(1) l string(1) o I don't know enough about the internals to say for sure, but perhaps text_string_to_array() could be implemented as creating a reference to the string that has a flag set that causes it to be allowed to be treated as an array. (A full conversion might be needed it were written to. For example, $a = text_string_to_array($s); $a[0] = 5; ) - Todd -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Re: foreach() for strings
On Mon, 2011-06-20 at 10:06 -0700, Stas Malyshev wrote: Hi! On 6/20/11 9:57 AM, Todd Ruth wrote: Iterators are nice. Having a text_string_to_array function would also be fine. For example: $s = 'hello'; foreach (text_string_to_array($s) as $x) { var_dump($x); } text_to_array($s) == str_split($s, 1) Does that have approximately the same performance as marking the string as being OK to use as an array? For example, $s = file_get_contents($big_file); foreach (str_split($s, 1) as $x) { f($x); } Are there performance issues with the above compared to: $s = file_get_contents($big_file); foreach (text_string_to_array($s) as $x) { f($x); } assuming text_string_to_array could be implemented as marking the string OK to use as an array. Again, I don't know enough about the internals. I'm just imagining a significant difference for very long strings between: $a1 = text_to_array('hello'); and $a2 = array('h','e','l','l','o'); $a1 and $a2 could act identically until a set occurred. For example, $a1['key'] = 5; would first trigger $a1 becoming just like $a2 so that the set could take place. Any string that has not been hit with text_string_to_array would lead to all the usual error messages some of us know and love and any string that has been hit with text_string_to_array would allow all the fancy features some people are seeking. I'm trying to find a way to please the people that want strings to act like arrays without ruining the day for those of us who are glad strings don't act like arrays. - Todd -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
[PHP-DEV] Avoiding Undefined index notices
I'm not arguing whether the following code fragment is good or bad (it's certainly less than ideal), but given the recent threads, I thought I'd show how I feel I've been encourage by php to code: ?php $x = array(); $y = 'something'; $temp = $x[$y]; $temp++; unset($temp); ? I'm not sure where (if anywhere) that technique is documented or even if it should be documented, but if you want to avoid Undefined index notices, that's one of the more terse approaches. The relative brevity is more obvious when the variable names are long and $temp is re-linked several times before unsetting. It's probably less clear than alternatives unless you see it often. Here is an application to the defaults for configurations thread: ?php $config = array(); $param = 'param1'; $temp = $config[$param]; $temp = $temp ?: 'default'; unset($temp); var_dump($config); ? It isn't beautiful, but it avoids writing $config[$param] more than once and it avoids the notices. - Todd -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Why is ereg being deprecated?
This thread inspired me to google for a POSIX to PCRE converter. I found a thread from this list from 2002: http://marc.info/?l=php-internalsm=103625548402350w=2 Ilia proposed a patch that would replace the ereg library with code that would allow an ereg userland call to be processed with the PCRE library (if I've understood the 2002 post correctly). I'm not complaining about dropping ereg nor taking a position on whether many or few would complain about dropping ereg. I just wanted to point out some past work that might be applicable lest someone start from scratch. BTW, thank you to all who have contributed to php. - Todd -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] non static function called as static one
On Wed, 2009-03-11 at 22:16 +0100, Olivier Doucet 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 ? In this case, $this is MySecondTest, which is relevant as it is the last object context. But to my mind, this code should not work like this. Imagine you are the developer of function MyTest. You want your code to interact with other classes and being bugproof. 'MyTest' class here seems OK: $this is expected to be 'MyTest' because function myfunc() is expected to be called in a non-static context. Programmer of the second function created this bug and this unattended behaviour. Maybe this can be done : 1/ Forbid calling the function in static context (How can I test this ? $this is not NULL there !). 2/ (or/and) Raise an error if a non static function is called as a static one (if E_STRICT is set, strict warning is already raised). 3/ Create two functions with the same name, one static and the other one not. Unfortunately, this can't be done (yet ?). What do you think ? What's your point of view on this ? I want your feedbacks before opening a bug ticket, as it is not strictly a bug... Comments from a lurker... For better or worse, it's been well documented that what you are describing is php's behavior and it would be an enormous backwards compatibility break to change it. Consider the following example, in which two generally unrelated class heirarchies have enough in common somewhere in the tree that some would be inclined to use multiple inheritance: ?php class ABase { public $a; } class A extends ABase { public $x; function f() { HelpsAandB::f(); } } class BBase { public $b; } class B extends BBase { public $x; function f() { HelpsAandB::f(); } } class HelpsAandB { function f() { var_dump($this-x); } } $example = new A; $example-x = 5; $example-f(); ? Is that a messed up design? Almost certainly. Is it a nightmare to re-design/re-implement many tens of thousands of lines of code that rely on such behavior? Unfortunately, that's true also. (You may have guessed that I'm responsible for such code and most of it was written before I joined the company.) I like to think this rules out options 1 and 2. I'm not sure about option 3. Maybe there could be a function that returns whether the current function call is associated with the current object (ie whether it was called via :: or -). I'm not an internals expert. Maybe to address backwards compatibility and address the concern you raise, there could be a nonstatic keyword. php would throw an error if a function declared nonstatic is called using ::. - Todd -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] allow_call_time_pass_reference
On Thu, 2008-05-08 at 20:28 +0100, Steph Fox wrote: ... Does anyone have a good reason for keeping it switched on by default in PHP 5.3? Like, would switching it off by default break a lot of existing code, given that most users are a bit beyond PHP 3 now? Well, I can at least comment on how it is used in the code that I inherited. First it must be noted that the following throws a fatal error: function f($x=5) { There are functions in our application that will use information if it is available and update the information if it is provided, but don't absolutely require such information in the first place. I don't know of another clean way to do that besides call-time pass-by-reference. Here is a useless example of the functionality. (This is an example, and only an example. In the event of real code, something useful would be accomplished. ;) ) ?php // $x is sometimes received by reference function f($x=5) { if ($x 10) { print blue\n; $x += 10; $retval = true; } else { print green\n; $x += 20; $retval = false; } return $retval; } f(); f(10); // In this case info is provided, but the update is discarded $y=5; f($y); f($y); ? Without call-time pass-by-reference, that becomes: function g($x) { if ($x === null) { $x = 5; } if ($x 10) { print blue\n; $x += 10; $retval = true; } else { print green\n; $x += 20; $retval = false; } return $retval; } $y = null; g($y); $y = 10; g($y); $y=5; g($y); g($y); So, without call-time pass-by-reference, if blocks would be needed to set defaults and temp variables would be needed anywhere an rvalue is used as an argument. It's true that the former has more opportunities for design error and without the comment about $x being received by reference there could be confusion, but going back and changing all that code is not desirable. Easier to read is always a tricky argument, but I'm sure many would find the first code above easier to read. - Todd -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] allow_call_time_pass_reference
On Thu, 2008-05-08 at 22:58 +0200, Hannes Magnusson wrote: On Thu, May 8, 2008 at 10:08 PM, Todd Ruth [EMAIL PROTECTED] wrote: On Thu, 2008-05-08 at 20:28 +0100, Steph Fox wrote: ... Does anyone have a good reason for keeping it switched on by default in PHP 5.3? Like, would switching it off by default break a lot of existing code, given that most users are a bit beyond PHP 3 now? Well, I can at least comment on how it is used in the code that I inherited. First it must be noted that the following throws a fatal error: function f($x=5) { No it doesn't. That line does however not work exactly as you would expect.. Quite right. I should have said leads to fatal errors. It doesn't throw a fatal error on it's own, but if you have old code that you must maintain in which a function is sometimes called as f(), sometimes called as f(10), and sometimes called as f($y), trying to fix it with the declaration above will lead to fatal errors for the f(10) calls. (The defaulting part isn't the problem for that case; it's using a non-variable when a reference is needed that leads to the fatal error.) BTW, in php4, there was an incentive to use call-time pass-by-reference. Calling f(g()) was a very bad thing if f always accepted its parameter by reference. There are a number of other similar cases. In php5 (and the last few releases of php4), it's still bad, but at least memory doesn't get corrupted now. In contrast, not declaring f to accept its parameter by reference and instead using call-time pass-by-reference was (and is) safe (though deprecated). - Todd -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Float comparison
On Fri, 2008-05-02 at 23:52 -0400, Cristian Rodríguez wrote: Todd Ruth escribió: Most people don't care about floating numbers beyond a certain number of digits. That's the main flaw in your suggestion, most people.. the language should be correct, do the real right thing. Would you suggest that the real right thing is to print 100 digits by default? That argument could be made, but I think everyone agrees that as a practical matter, most people don't care about most of the digits so a default is set for precision that makes most people happy without ever even knowing the precision setting exists. Why should things be any different for other non-progressing uses of a float? (By non-progressing, I mean a use of a float that doesn't affect digits of another float, such as doing a comparison or using a float as an array key.) A comparison_precision value could be set to 14 by default. That will make most people happy for most cases without ever even thinking about it. If someone wants more digits, they care enough about floats to likely be aware of such settings. (and if they don't they need to be aware of all these issues and the improvements I'm encouraging wouldn't help them - not being able to help that small percent isn't a reason not to help the others) There seems to be an attitude of that's what you get for using floats. In c, you can't compare strings intuitively because you'd be comparing addresses not strings. php hides that ugly bit of internals, so the programmer can compare two strings without worrying about all that. No one says That's what you get for using strings; you always need to make a function call to compare strings. Why not let the programmer get intuitive behavior for floats too? The people who want to have incredibly small epsilons know their stuff and would use a vary large value for comparison_precision (and if they don't know their stuff need to learn it any case). - Todd -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Float comparison
I'm afraid you'll find Pierre's response representative. The php devs seem to consider the fact that a theoretically perfect == doesn't exist to mean that the improvements that would cover 99.9% of user issues with float == shouldn't be made. It could be worse, however. At least the cast to string works as one would expect. Just imagine if those who oppose improving == had their logic extended to the cast to string. Php might to the following: ?php $x=.3+.4+.5; print $x\n; ? might output 1.19996447286321199499070644378662109375 If someone filed a bug report, they could refer you to that paper and tell you there's no bug because you're trying to get a string from float and you never know what you might get. So we can at least be glad that casts to string work as the average person would expect. We can hope that someday the fact that the cast to string works as expected will inspire them believe that making == work as expected wouldn't be a bad thing. Seriously though, the biggest issue I see with improving == is the implication for other features. For example, what should the following code do? $a[.3+.4+.5] = hello; print isset($a[1.2]) Should floats be allowed as array indices? I would say no because I'd rather floats be converted to strings before being used as array indices. That would make the above code work as the average person would expect. Unfortunately, that would be a huge BC break. However, perhaps the perfect shouldn't be the enemy of the good and we shouldn't let the inability to fix floats as array indices be a reason not to improve ==. - Todd On Fri, 2008-05-02 at 19:04 +0200, Pierre Joye wrote: On Fri, May 2, 2008 at 6:52 PM, Jonathan Bond-Caron [EMAIL PROTECTED] wrote: Hi, I'm new to the PHP internals list and I'm posting an issue I'm sure has been mentioned before -- float comparison I'd like to know if there are reasons not to change the default behavior when comparing floats. i.e. This would seem logical to me: $test = 19.6*100; if((float)(string)$test == (double)1960) echo GOOD BEHAVIOR; // Implicitely convert the float to string then float (en_US locale) if($test == (double)1960) echo THIS SHOULD PASS by casting (float)(string)$test internally...; else echo NOT GOOD BEHAVIOR; // Exact comparison would still fail if($test !== (double)1960) echo GOOD BEHAVIOR; Any reason why $test == (double)1960 should fail? I realized we are comparing two floats, but couldn't php internally convert to string then float - for the non strict (===) case From our bug report: Floating point values have a limited precision. Hence a value might not have the same string representation after any processing. That also includes writing a floating point value in your script and directly printing it without any mathematical operations. If you would like to know more about floats and what IEEE 754 is read this: http://docs.sun.com/source/806-3568/ncg_goldberg.html Thank you for your interest in PHP. We use this text as automatic reply for bugs about floating points (aka bogus). Cheers, -- Pierre http://blog.thepimp.net | http://www.libgd.org -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Float comparison
On Fri, 2008-05-02 at 11:41 -0700, Rasmus Lerdorf wrote: Stefan Walk wrote: And you'll quickly see that the cast to string before comparision is a bad idea, because: $ php -dprecision=1 -r 'var_dump((string)1.4 == (string)1.1);' bool(true) Having display settings affect comparisions seems like a really bad idea to me ;) Yup, it would be a fatal flaw in the language if that ever came to be. -Rasmus Most people don't care about floating numbers beyond a certain number of digits. If precision were the only ini setting that gave us an idea of how much the person cared, I think it would be fair to use the setting or introduce a new setting. As it happens, there is another setting. How would you feel about this returning true: php -dserialize_precision=1 -r 'var_dump(1.4 == 1.1);' Setting serialize_precision to 1 is a very strong statement of not caring about those digits. Personally, I don't care about more than about 6 digits and I don't do much math, so I could set it to 8 digits and be happy. Not everyone has the luxury of controlling ini settings, but for those that do, this would be much nicer than having (string)(float)$s === (string)$f and as you point out, the casts aren't perfect anyway. (In my case, the casts are somewhat appropriate, because I'm checking whether a user input is the same as the default that was provided. The default came from casting the result of a computation to a string. Yes, there are other more efficient ways to deal with that too.) If that still doesn't feel right, how about: php -dcomparison_precision=1 -r 'var_dump(1.4 == 1.1);' could return true. The default for comparison_precision would be the same as the default for precision. It could be interesting to apply comparison_precision when a float is used as an array index... I'm not sure whether that would do BC harm off the top of my head. There may be other cases where floats are used as an r-value that this might help. I suppose anything involving a float that does not lead to the production of a new float would be well served by this. For example, $z=$x+$y shouldn't use this feature at all because all of $x's and $y's bits should be used and all of the bits of $z should be kept for now. in_array() would be friendly to use this feature though. Better? (BTW, Pierre, the statement X considers the fact that S1 to mean that S2 is a statement _agreeing_ with S1. It calls into question whether S1 implies S2. I agree a perfect solution to the problems we're discussing don't exist. I don't think that implies that improvements should not be made.) - Todd -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] '1.8' == 1.8 can return false
I'd take that as proof of a design flaw in having php doing string to float comparison by casting the string to float instead of the float to a string, but you've got me - the documentation does say the string will be converted to a float and not vice-versa. If it wouldn't be a bad BC break, I think there'd be a lower WTF by doing the cast the other way. == means are they the same and === means are they the SAME. With ==, '1.8' should match any float that would be displayed as 1.8. (Of course, with === they aren't even the same type, so you're false from the start.) I say should from an anti-WTF perspective. Again, I must bow to the spec and you have me there. Thanks for saving me the hours of discovering all this via debugging. Please consider the switching of casts for string==float for the suggestion box. - Todd On Fri, 2008-04-11 at 20:29 -0700, Rasmus Lerdorf wrote: There is no bug here. Please read: http://docs.sun.com/source/806-3568/ncg_goldberg.html -Rasmus Todd Ruth wrote: I'm thinking there must be a bug in the heart of php causing this. I'll debug it, but I haven't looked at php source code in a few years and would like a tip as to which files are involved in evaluating ==. Here is a fragment from my code and the output: ... print pre\n; var_dump($max); var_dump($nms); var_dump($nms == $max); $max = (float)$max; $nms = (string)$nms; var_dump($max); var_dump($nms); var_dump($nms == $max); $max = (string)$max; $nms = (float)$nms; var_dump($max); var_dump($nms); var_dump($nms == $max); print /pre\n; ... string(3) 1.8 float(1.8) bool(false) float(1.8) string(3) 1.8 bool(true) string(3) 1.8 float(1.8) bool(true) I found this using php 5.2.3. I just upgraded to php 5.2.5 and am receiving the exact same result. Obviously, I can't reproduce it with a simple var_dump(1.8==1.8). :( I guess something is getting corrupted, and I will add debug output until I find out what (or Murphy removes the problem by adding debug output; then I'm not sure what I'll do). Thanks for any tips on which files I should look at it. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] '1.8' == 1.8 can return false
Clicked Send too fast. For the suggestion box, let me instead suggest that for string $s and float $f: $s == $f (a string being compared to a float) be the same as (string)(float)$s === (string)$f instead of (float)$s === $f (as it is today if my understanding is correct) Since the current behavior is effectively undefined in any case in which the two interpretations would give different results, I'd guess that change could probably be made without breaking BC. The only problem would be if someone relied on the change and their code was run on an old version of php. I'll go back to my corner now. Thanks for listening... - Todd On Fri, 2008-04-11 at 22:59 -0700, Todd Ruth wrote: I'd take that as proof of a design flaw in having php doing string to float comparison by casting the string to float instead of the float to a string, but you've got me - the documentation does say the string will be converted to a float and not vice-versa. If it wouldn't be a bad BC break, I think there'd be a lower WTF by doing the cast the other way. == means are they the same and === means are they the SAME. With ==, '1.8' should match any float that would be displayed as 1.8. (Of course, with === they aren't even the same type, so you're false from the start.) I say should from an anti-WTF perspective. Again, I must bow to the spec and you have me there. Thanks for saving me the hours of discovering all this via debugging. Please consider the switching of casts for string==float for the suggestion box. - Todd On Fri, 2008-04-11 at 20:29 -0700, Rasmus Lerdorf wrote: There is no bug here. Please read: http://docs.sun.com/source/806-3568/ncg_goldberg.html -Rasmus Todd Ruth wrote: I'm thinking there must be a bug in the heart of php causing this. I'll debug it, but I haven't looked at php source code in a few years and would like a tip as to which files are involved in evaluating ==. Here is a fragment from my code and the output: ... print pre\n; var_dump($max); var_dump($nms); var_dump($nms == $max); $max = (float)$max; $nms = (string)$nms; var_dump($max); var_dump($nms); var_dump($nms == $max); $max = (string)$max; $nms = (float)$nms; var_dump($max); var_dump($nms); var_dump($nms == $max); print /pre\n; ... string(3) 1.8 float(1.8) bool(false) float(1.8) string(3) 1.8 bool(true) string(3) 1.8 float(1.8) bool(true) I found this using php 5.2.3. I just upgraded to php 5.2.5 and am receiving the exact same result. Obviously, I can't reproduce it with a simple var_dump(1.8==1.8). :( I guess something is getting corrupted, and I will add debug output until I find out what (or Murphy removes the problem by adding debug output; then I'm not sure what I'll do). Thanks for any tips on which files I should look at it. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
[PHP-DEV] '1.8' == 1.8 can return false
I'm thinking there must be a bug in the heart of php causing this. I'll debug it, but I haven't looked at php source code in a few years and would like a tip as to which files are involved in evaluating ==. Here is a fragment from my code and the output: ... print pre\n; var_dump($max); var_dump($nms); var_dump($nms == $max); $max = (float)$max; $nms = (string)$nms; var_dump($max); var_dump($nms); var_dump($nms == $max); $max = (string)$max; $nms = (float)$nms; var_dump($max); var_dump($nms); var_dump($nms == $max); print /pre\n; ... string(3) 1.8 float(1.8) bool(false) float(1.8) string(3) 1.8 bool(true) string(3) 1.8 float(1.8) bool(true) I found this using php 5.2.3. I just upgraded to php 5.2.5 and am receiving the exact same result. Obviously, I can't reproduce it with a simple var_dump(1.8==1.8). :( I guess something is getting corrupted, and I will add debug output until I find out what (or Murphy removes the problem by adding debug output; then I'm not sure what I'll do). Thanks for any tips on which files I should look at it. Thanks, Todd -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] 5.2.5 and static calls
I compiled 5.2.5 last night and noticed that it effectively breaks all static calls which have no static keyword assigned in the function's definition (sorry, a bit clumsy here). How about waiting to break people's :: calls to non-static functions until some number of releases or amount of time after traits are introduced? For years, making :: calls to non-static functions has been the php way to write traits. (OK, this lacks a lot of the features of full traits, but it's better than nothing.) Isn't it fair to provide an alternative and some time to switch to the alternative before making the old way fatal? In case it isn't clear how you could write a trait, here's a silly example: (A full example would have more interesting code that would be re-used by a variety of objects, but this example demonstrates the key abilities of php without the distractions of doing something useful.) ?php class Trait { function e() { print $this-g().\n; } function f() { Trait::e(); } } class Obj { function g() { return 5; } function h() { Trait::f(); } } $o = new Obj; $o-h(); ? -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] RFC: Traits for PHP
In case anyone is really excited about traits and traits don't make it in soon, I'll point out that something similar has been available in php for years. We've been implementing traits based on the fact that $this has a different meaning in php than in other languages. In php, $this is the most recent object context. So... it's easy to create a trait class and make calls to it from your non-trait class using :: syntax. - calls within the trait class automatically go back to the non-trait class. This makes the purists shudder and they added a STRICT message for it. (If you're a purist please don't bother replying with how evil I am. I already know this makes your stomach turn.) It obviously isn't as clean as a well defined trait feature (or doing a re-architecture of your app to elimate the need), but if you need traits today, this may work for you. - Todd -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Re: Syntactic improvement to array
Would this be legal? function f() { return [ 1, 2 ]; } $x = [ $a, $b ] = f(); In the end, would we have...? $a = 1; $b = 2; $x = array(1,2); I'm not trying to be positive or negative about the syntax. I'm just testing somewhat edge cases. - Todd On Mon, 2007-02-05 at 10:06 -0800, Andrei Zmievski wrote: ... The way I view [] is that it creates an array context. When the context is an RHS, it instantiates an array. When it's an LHS, the context deconstructs the array. -Andrei -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] E_STRICT/E_DEPRECATED
I'm not a voter, but I'd like to lobby for a fancier E_STRICT... E_STRICT is sounding more and more like runtime lint. I very much miss lint. (I'm sure it's still around, but I've been programming in only php for the last few years.) A key feature of lint that made it usable was that you could have a file listing error codes that you always wanted to ignore and you could use a comment adjacent to your bad code to tell lint to ignore that specific case. I think a previous thread talked about using codes in the messages to allow easy bulk filtering, so the file of codes to skip isn't absolutely necessary. Being able to put in a comment that causes the E_STRICT to be skipped for an adjacent bit of bad code would be very friendly. We make sure all of our code is NOTICE free (for as many code paths as we can stand to test) before it goes out the door. I'm sure many others do the same. To be able to do the same with E_STRICT would be a great benefit, but I think a larger portion of the user base would adopt it if there were ways to turn down the volume when you really want to ignore the guidelines for ideal code. I have no idea how difficult such a feature would be; I just wanted to point out how useful it would be. (As always, thanks for all that all of you do!) BTW, the trend on the list toward separating STRICT and DEPRECATED and only putting deadly stuff in the DEPRECATED bin is very much appreciated. For a while I was guessing we'd never be able to upgrade our php! I'm still assuming 5.2 is unusable based on the threads about fatal errors, but it seems all this will be sorted out for 5.3 at the latest. That's better than being on 5.1 for the rest of our lives. Thanks, Todd -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] RfC: rethink OO inheritance strictness
Hooray! Thank you, Zeev! I'd nearly given up hope on ever moving to a new version of php. (Actually, I'm still doomed for using $this in static calls to an unrelated class, but every bit of avoiding fatal errors helps.) Our code may not be OO, but it's definitely php. ;) Thanks, Todd On Wed, 2006-08-02 at 15:43 +0300, Zeev Suraski wrote: My recommendation: - Add a new flag to methods (at the implementation level) that will allow to flag them as 'strict' - In case such a strict method is improperly overridden - error out (E_ERROR) - In case a non-strict method is improperly overridden - emit E_STRICT - Consider adding userland ability to set entire classes or methods as strict Most people who use 'strict OO' will have E_STRICT enabled and have their code E_STRICT clean, so providing userland support for tagging classes/methods as strict is probably not really necessary. Zeev -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] fatal static call in php 6.0?
On Thu, 2006-05-25 at 14:53 +0200, Marcus Boerger wrote: There is no way you can write heavy oo using code that supports PHP 4 and PHP 5.2 without a version check every here and there, so i don't see this as an argument. It is a fact that 4 and 5 have very different object models. Sort of. The fact that $object1 = $object2 didn't mean $object1 = $object2 in php4 drove us crazy, so each of our objects keeps its data in an array. For us, moving from 4 to 5 was mostly about adding strtolowers. We already had our own cloning function, so the only reason we can't go back to 4 is that we're using Derick's date stuff. That was the killer feature for us that got us to php 5. The object stuff has not been an issue. Perhaps you're implying that my life will be difficult if I move from 5.1 to 5.2, but hopefully that won't be too painful. BTW, the phpt I posted that uses $this in a static call doesn't even give a strict message in 5.1.2. It passes with 0 messages even with E_ALL|E_STRICT. BTW, a big thanks to Derick for the timezone feature! (not to overshadow my thanks to you for the numerous handy patches I've seen you post!) Thanks, Todd -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] fatal static call in php 6.0?
In php5 this works even without an instanceof relationship. (I'm running 5.1.2 and this test gets a PASS from run-tests.php.) I know the following test case does not even remotely follow good OO design principles, but it's hard to imagine us going back to the drawing board with our app. Please don't break the following in php6 just to teach me a lesson about OO design. If there's a repository of someone will complain about a BC break if this changes tests, please add the following: --TEST-- test that $this survives in a semi-static call --FILE-- ?php class TheParent { public $x = 3; } class UglyUncle { function f() { $this-x = 5; } } class Child extends TheParent { function f() { UglyUncle::f(); } } $c = new Child(); var_dump($c-x); $c-f(); var_dump($c-x); ? --EXPECT-- int(3) int(5) Thanks, Todd On Mon, 2006-05-15 at 19:41 -0700, Andi Gutmans wrote: I don't see why it has to be a fatal error. If there's an instanceof relationship we can keep $this. If not, we should not pass $this (which I believe we already do in PHP 5), in which case the author would have to pass $this if he wants to change public properties. Andi At 12:49 PM 5/15/2006, Edin Kadribasic wrote: Todd Ruth wrote: I don't see benefits of making semi-static fatal that make it worth keeping those of us with large apps that depend on semi- static from upgrading to php6. My sentiments exactly. OO purity/strictness do now work well with PHP's main strength -- its dynamicity. Edin -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php -- Todd Ruth [EMAIL PROTECTED] -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
[PHP-DEV] fatal static call in php 6.0?
On Mon, 2006-05-15 at 06:51 -0400, Greg Beaver wrote: ... Side note: calling functions statically that do not have a static modifier causes E_STRICT. Hello PEAR::isError() This is of course going to be a fatal in PHP 6, but it is now the most common E_STRICT I see in PHP4-based code. Yikes! Please say it isn't so! There are significant portions of our app that rely on php's ability to make semi-static calls. It would never be worth the cost of upgrading to php6 if that were the case. It's not the best style, but we have scores of classes that have several members in common and need common functionality for those members. In php5 and earlier, you can add helper classes and call helper functions with the :: syntax. The helper can access all of the members of the main class as if it were its own. The right thing to do would be to step back in the design and move the members to other classes, etc., but as practical matter, sometimes that's just not worth the effort to make such drastic changes to code that's developed by accretion. Another use is that we have core data that most classes keep in an $application member variable. It's sort of like a global, but to allow for a couple instances of a class to work on different app data, we've taken the member route instead of the global route. php is a nice language for this in that we don't have to pass $application to every static function we call. The static function has access to $this-application, because everyone who calls the static function has the application member. Please don't fatal error this code in php 6! Thanks for listening, Todd -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] fatal static call in php 6.0?
On Mon, 2006-05-15 at 20:27 +0200, Marcus Boerger wrote: Monday, May 15, 2006, 6:03:14 PM, you wrote: On Mon, 2006-05-15 at 06:51 -0400, Greg Beaver wrote: ... Side note: calling functions statically that do not have a static modifier causes E_STRICT. Hello PEAR::isError() This is of course going to be a fatal in PHP 6, but it is now the most common E_STRICT I see in PHP4-based code. Yikes! Please say it isn't so! There are significant portions of our app that rely on php's ability to make semi-static calls. It would never be worth the cost of upgrading to php6 if that were the case. It's not the best style, but we have scores of classes that have several members in common and need common functionality for those members. In php5 and earlier, you can add helper classes and call helper functions with the :: syntax. The helper can access all of the members of the main class as if it were its own. The right thing to do would be to step back in the design and move the members to other classes, etc., but as practical matter, sometimes that's just not worth the effort to make such drastic changes to code that's developed by accretion. Another use is that we have core data that most classes keep in an $application member variable. It's sort of like a global, but to allow for a couple instances of a class to work on different app data, we've taken the member route instead of the global route. php is a nice language for this in that we don't have to pass $application to every static function we call. The static function has access to $this-application, because everyone who calls the static function has the application member. Please don't fatal error this code in php 6! Thanks for listening, Todd Ever heared of the concept named root class? Yes, but it isn't a substitute for the semi-statics. Including comments, etc., our php files total about 130,000 lines. If it were a small, simple app, I could shove the helpers into a root class and it wouldn't be much worse than the search replaces needed to get to php5. The arguments against our code would be the standard arguments against multiple inheritance. (The semi- statics provide something very similar to multiple inheritance.) Like many large apps that have evolved over many years, this isn't because it was designed that way; it is because much of it wasn't designed at all. It just grew. The good news is that it ran great on php4 and it hasn't been too much trouble to get rid of the issues with getting it to run great on php5. I'm hoping php6 doesn't give up so much backward compatibility that we'll never be able to use it. BTW, I've tried to come up with a short example to give a flavor of what I want to preserve, but anything short is too easy to refactor and say it should have been done differently. It's true that many aspects of our app should have been done differently, but its difficult to change something so large. I don't see benefits of making semi-static fatal that make it worth keeping those of us with large apps that depend on semi- static from upgrading to php6. Is there a significant performance enhancement in the engine that depends on eliminating semi-static or somesuch? - Todd -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
[PHP-DEV] Upgrading php
I'd been ignoring the curly braces thread, but then I grepped my code and ... sure enough, I have curly braces that are used to index into strings. I don't care about this philosophically, but it makes me wonder about upgrade tools. I know I shouldn't ask this without volunteering to do it myself, but when a version of php comes out that makes such a change, is there any chance of having a tool that updates the code available at the same time? It seems to me that nothing understands php user code better than the core php code, so perhaps a tool could be written that uses the guts of php as a base. I suppose there are some IDEs that could do the job as well. Sadly, I still use vi, but I bet if something were written for emacs or eclipse, most people (even me) could learn to use it. I'm dreading going to php5. I hear that to avoid warnings/notices I'll need to convert a bunch of vars to publics. I'll need to wrap my get_classs with strtolowers. etc. It would be so wonderful to throw all my code at a tool that would change everything that can be easily changed and give me a list of spots I need to look at manually. A lot of the changes don't take an overwhelming amount of time to do myself, but when you think about the thousands of users all doing the same conversions, it just makes sense for there to be a tool. It might also have the side benefit of reducing long threads about breaking old code. Perhaps this already exists and I've missed it. Perhaps it will never exist because it isn't enough fun to write. Just an idea... - Todd -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Upgrading php
On Thu, 2005-11-17 at 16:47 -0800, Rasmus Lerdorf wrote: Todd Ruth wrote: ... It would be so wonderful to throw all my code at a tool that would change everything that can be easily changed and give me a list of spots I need to look at manually. A lot of the changes don't take an overwhelming amount of time to do myself, but when you think about the thousands of users all doing the same conversions, it just makes sense for there to be a tool. It might also have the side benefit of reducing long threads about breaking old code. Perhaps this already exists and I've missed it. Perhaps it will never exist because it isn't enough fun to write. Just an idea... This is what the E_STRICT messages are for. If you turn them on (in PHP 5) you will get very specific messages about language-level issues in your code. -Rasmus I appreciate those messages. There are probably things that come up at runtime for which the E_STRICT messages are the only good option. (My guess is that it would be too much trouble to make a version of php that rewrites my source code on the fly. ;) ) On the other hand, my current upgrade approach is: - go to the new version - try to use all of my code paths and copy and paste the notices to a file - sed the file into a list of vi commands that take me to every line that generated a message - after recognizing the pattern for the simple fixes, define macros to do most of the work - Try to maintain consciousness while applying the macros over and over again. If I weren't nearly the last person on the planet to upgrade, it would be useful for me to at least post my vi macros somewhere. Perhaps if other people are following a similar approach, they could post whatever they use to get them over hurdles. The hope in my original email is that if php is clever enough to give me a message, it might be clever enough to just make the change too. I appologize again for bringing this up without providing any tools. I just wanted to make sure it was considered. Maybe there could be a spot on php.net where people are encouraged to post (or at least post links to) what helped them get through php transitions. Thanks again, Todd -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] return /* by reference */ new Foo() in PHP4
On Sat, 2005-10-08 at 21:57 +0200, Matthias Pigulla wrote: ... This was bug #33558 and has been fixed in 4.4.1RC1. Does that give 34551 any chance of being fixed? 33558 is just an annoying notice, but 34551 is a real BC break in 4.4 that wasn't documented and will likely continue to bite people who don't corrupt memory and think they can safely move to 4.4. - Todd -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Reference handling change and PHP 4.4.0
On Mon, 2005-09-19 at 22:36 +0400, Antony Dovgal wrote: 1) They are only notices, you don't *have* to fix them as they can be safely silenced. It would be nice if they could be safely silenced, but the bug I just filed about the BC break in 4.4 (#34551) was just marked bogus, so it looks like you must fix the notices or risk having the behavior of your code change (even if you never corrupted any memory). I am grateful for the notices and even more grateful for the resolving of the memory corruptions. For the sake of many other users, I'm frustrated that there was a BC break that came with the notices (beyond the advertised internal api change). (The BC break is that $y = $x; $y = ... is no longer guaranteed to disconnect $y from $x.) - Todd 2) Yes, you *can* fix them since they tell you about potential problems in your code. -- Wbr, Antony Dovgal -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Re: Reference handling change and PHP 4.4.0
Aha! That was the inspiration I needed to get the right combination of s. The following bit of code behaves differently under 4.3 vs 4.4: ?php function f($a) { return $a; } $x = array('a','b','c'); foreach (array_keys($x) as $k) { // I think the following line disconnects $y in 4.3 // but leaves $y connected in 4.4 $y = f($x[$k]); $z[] = $y; } var_dump($x); var_dump($z); ? My guess would be that in 4.3 the engine tries to do the reference even though it may be dangerous. That would disconnect $y from the previous $z[]. 4.4 knows the reference is impossible and leaves $y connected to the previous $z[]. Is that analysis correct, engine gurus? Thanks, Colin! - Todd On Fri, 2005-09-16 at 10:55 +1000, Colin Tucker wrote: Hello again, Wow, this thread generated more heat than I thought it would, I basically just wanted to know the reasoning behind making the change to PHP4, unfortunate I guess for all involved that it went downhill. I have learned much in the past few days, at any rate. As mentioned, my code actually broke following the switch to 4.4.0, in addition to logging hundreds of E_NOTICE errors. It's taken me some time to track down where it's going wrong, but I think I've found out the culprits involved. It's complicated, I'll try to explain it all. The problem was related to components of my web app framework (which is similar to Struts, and incidently, now being phased out for a MUCH more lightweight, PHP5-based framework), in particular, an array of attributes, view helper classes and the creation of DAOs (data access objects) at runtime via XML configuration, which would look like this: daos dao name=dao.freight class=FreightDAO component=Generic/Commerce/DAO/FreightDAO.php / dao name=dao.customer class=CustomerDAO component=Generic/Commerce/DAO/CustomerDAO.php / dao name=dao.order.status class=OrderStatusDAO component=Generic/Commerce/DAO/OrderStatusDAO.php / /daos This XML would be parsed and the relevant DAO instances would be created and recorded in attribute scope for the current application module instance. For each dao node, the following code would be called (where $daoClass and $daoComponent are extracted from the XML attributes): $dao = $this-_createDAO($daoClass,$daoComponent); if ($dao) { $this-module-setAttributeByReference($name,$dao); } Notice it assigns by reference, however I discovered that the _createDAO() method was not *returning* by reference: function _createDAO($daoClass=null,$daoComponent=null) { // Obtain Database Object: $database = $this-module-findDatabase(); if (is_null($database)) { trigger_error($this-error(ERROR_DB_COULD_NOT_OBTAIN)); } else { // Obtain Database Connection: $connection = $database-getConnection(); if (is_null($connection)) { trigger_error($this-error(ERROR_DB_COULD_NOT_CONNECT)); } else { // Create DAO Instance: $cmp = new ClassComponent($daoClass,$daoComponent); $dao = $cmp-getInstance(); if ($dao) { $dao-setConnectionByReference($connection); return $dao; } } } return NULL; } What was happening under PHP 4.4.0 is when the newly created DAO was added to the module as an attribute (setAttributeByReference), a new attribute would be created, but ALL existing DAOs in the attribute scope would become the newly added DAO, for example: (create and set the dao.freight attribute): attributes (array) { [dao.freight] = FreightDAO Object } (create and set the dao.customer attribute): attributes (array) { [dao.freight] = CustomerDAO Object [dao.customer] = CustomerDAO Object } (create and set the dao.order.status attribute): attributes (array) { [dao.freight] = OrderStatusDAO Object [dao.customer] = OrderStatusDAO Object [dao.order.status] = OrderStatusDAO Object } Simply by adding the ampersand to the _createDAO() method, like so: function _createDAO($daoClass=null,$daoComponent=null) { } ...rectified the problem (however did not make hundreds of E_NOTICE's disappear, of course ;)). The question is, why did this problem not occur before 4.4.0? Is this an example of the memory corruption? Regards, Colin. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Re: Reference handling change and PHP 4.4.0
I should have said something about a fix. I guess the fix would be to always unset any variable that is attempting to be assigned by reference before doing anything else with the variable. Yes? That would at least fix BC for the example I gave (and I think Colin's example). If $y were unset (based on the = even the can't really be used) before being set, the behavior would have matched 4.3. - Todd On Thu, 2005-09-15 at 22:08 -0700, Todd Ruth wrote: Aha! That was the inspiration I needed to get the right combination of s. The following bit of code behaves differently under 4.3 vs 4.4: ?php function f($a) { return $a; } $x = array('a','b','c'); foreach (array_keys($x) as $k) { // I think the following line disconnects $y in 4.3 // but leaves $y connected in 4.4 $y = f($x[$k]); $z[] = $y; } var_dump($x); var_dump($z); ? My guess would be that in 4.3 the engine tries to do the reference even though it may be dangerous. That would disconnect $y from the previous $z[]. 4.4 knows the reference is impossible and leaves $y connected to the previous $z[]. Is that analysis correct, engine gurus? Thanks, Colin! - Todd On Fri, 2005-09-16 at 10:55 +1000, Colin Tucker wrote: Hello again, Wow, this thread generated more heat than I thought it would, I basically just wanted to know the reasoning behind making the change to PHP4, unfortunate I guess for all involved that it went downhill. I have learned much in the past few days, at any rate. As mentioned, my code actually broke following the switch to 4.4.0, in addition to logging hundreds of E_NOTICE errors. It's taken me some time to track down where it's going wrong, but I think I've found out the culprits involved. It's complicated, I'll try to explain it all. The problem was related to components of my web app framework (which is similar to Struts, and incidently, now being phased out for a MUCH more lightweight, PHP5-based framework), in particular, an array of attributes, view helper classes and the creation of DAOs (data access objects) at runtime via XML configuration, which would look like this: daos dao name=dao.freight class=FreightDAO component=Generic/Commerce/DAO/FreightDAO.php / dao name=dao.customer class=CustomerDAO component=Generic/Commerce/DAO/CustomerDAO.php / dao name=dao.order.status class=OrderStatusDAO component=Generic/Commerce/DAO/OrderStatusDAO.php / /daos This XML would be parsed and the relevant DAO instances would be created and recorded in attribute scope for the current application module instance. For each dao node, the following code would be called (where $daoClass and $daoComponent are extracted from the XML attributes): $dao = $this-_createDAO($daoClass,$daoComponent); if ($dao) { $this-module-setAttributeByReference($name,$dao); } Notice it assigns by reference, however I discovered that the _createDAO() method was not *returning* by reference: function _createDAO($daoClass=null,$daoComponent=null) { // Obtain Database Object: $database = $this-module-findDatabase(); if (is_null($database)) { trigger_error($this-error(ERROR_DB_COULD_NOT_OBTAIN)); } else { // Obtain Database Connection: $connection = $database-getConnection(); if (is_null($connection)) { trigger_error($this-error(ERROR_DB_COULD_NOT_CONNECT)); } else { // Create DAO Instance: $cmp = new ClassComponent($daoClass,$daoComponent); $dao = $cmp-getInstance(); if ($dao) { $dao-setConnectionByReference($connection); return $dao; } } } return NULL; } What was happening under PHP 4.4.0 is when the newly created DAO was added to the module as an attribute (setAttributeByReference), a new attribute would be created, but ALL existing DAOs in the attribute scope would become the newly added DAO, for example: (create and set the dao.freight attribute): attributes (array) { [dao.freight] = FreightDAO Object } (create and set the dao.customer attribute): attributes (array) { [dao.freight] = CustomerDAO Object [dao.customer] = CustomerDAO Object } (create and set the dao.order.status attribute): attributes (array) { [dao.freight] = OrderStatusDAO Object [dao.customer] = OrderStatusDAO Object [dao.order.status] = OrderStatusDAO Object } Simply by adding the ampersand to the _createDAO() method, like so: function _createDAO($daoClass=null,$daoComponent=null) { } ...rectified the problem (however did not make hundreds of E_NOTICE's disappear, of course ;)). The question is, why
[PHP-DEV] Re: Reference handling change and PHP 4.4.0
For the record, I have no idea how the 4.3 - 4.4 change could trigger such a bug. I just pointed out that we've hit the symptom Colin described many times in our company with code (yes, bad code) of the form: ?php function f($y) { return $y; } $x = array('a','b','c'); foreach ($x as $y) { // The following line is a bad use of . It doesn't // do any good and ends up causing all the members of $z // to be references to eachother. $z[] = f($y); } var_dump($x); var_dump($z); ? I've played with many flavors of this user-bug, adding and subtracting s, but have been unable to get different behavior between 4.3 and 4.4. Colin, when you find the code that went wild in the switch to 4.4, please post it. I'm sure there are others that are as curious as I am. (There may even be someone nice enough to fix the BC break if it doesn't mean reintroducing memory corruptions.) As long as I'm posting, I might as well put in a thank you note for the notices. I know they're generating a lot of heat, but it's made it s much easier to fix all of the novice uses of s in our code. Thanks, Todd ... I may not have provided any code, but this problem description was enough for Todd Ruth to send me a very helpful and informative e-mail on the matter (i.e. everything the same as the last added bugs), which shall help me greatly in tracking it down (thanks again, Todd!). Regards, Colin. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Re: References Problem Patch
Derick, Thank you! Thank you! Thank you! The problems with references are one of the main reasons I watch this list. As others have stated, with many tens of thousands of lines of code, it is extremely painful to figure out which misplaced or missing has caused php to lose its mind. The fact that php loses its mind in these cases has left me with the impression that php is sort of a second class language. Putting the reference bugs to rest are the most important bug fixes I can imagine. (No, I don't think it will be feasible for us to move to php 5 anytime soon.) Thank you! - Todd Ruth On Mon, 2005-05-30 at 16:44 +0200, Derick Rethans wrote: On Mon, 30 May 2005, Christian Schneider wrote: Derick Rethans wrote: If you decide not to fix the 4.x branch then we'd minimally need an easily accessible document describing the known problems and work-arounds IMHO. As I tried to do that in our large code base, I would say that's totally not possible to do. There is no way you know you're doing someting wrong, as there are no warnings and go through 200k+ lines of code without missing an instance is impossible. That's a misunderstanding then. I was meaning work-arounds on the user side like avoiding certain constructs. That's what I meant too. Our large code base is a PHP application. Derick -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] segmentation fault when passing arguments by reference or importing global variables
Ahh... my favorite topic. I think I covered all the cases our company has hit in the following message to this list: http://marc.theaimsgroup.com/?l=php-devm=109631219107237w=2 I've never seen a response as to whether there is hope for fixes of these problems. I ended up hacking at an already very ugly p*rl script (a language that shouldn't be mentioned on this list) to look for attempts to use non-referencable things as references. Unfortunately, not only is it in the language which must not be named, but it also makes some assumptions about the code based on company standards. I keep my fingers crossed that someone with appropriate skills will write a tool to do the check right. The problems can be painful to find. e.g. function g() { return NULL; } function h($x) { $x = 5; } h(g()); can cause php to crash. (Don't bother trying to reproduce it though. It only causes a crash with a _lot_ of other php code with it to make things interesting.) Good luck! - Todd On Mon, 2005-02-21 at 21:21 -0500, Michael Walter wrote: I've as well experienced this problem several times (in a medium-size code base). By returning-by-reference in the wrong places, do you mean something like function foo() { return 10;} $bar=foo(); I'm pretty convinced that even with correct (in that respect) code the crash still occurs. Michael On Mon, 21 Feb 2005 15:56:34 -0300, Martin Sarsale [EMAIL PROTECTED] wrote: Derick Rethans wrote: I've been noticing the same things, and still trying to figure out where it happens. It has most likely to do with returning-by-reference in the wrong places. What do you mean with returning by reference in the wrong places? could you give me an example? -- No virus found in this outgoing message. Checked by AVG Anti-Virus. Version: 7.0.300 / Virus Database: 266.2.0 - Release Date: 2/21/2005 -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Type hints with null default values
On Tue, 2004-10-19 at 02:42, Christian Schneider wrote: The only restrictions I see is that it makes the parameter optional as well (something I don't consider a problem as it is probably desirable in most cases anyway to be able to leave out an explicit null) and that it only works if no mandatory parameter follows, e.g. function method(MyClass $obj = null, $mandatory); is not possible. Not a real problem either IMHO. Is it an implementation difficulty that makes that example not possible? If not, I don't see a problem with it. It just means the first parameter is optional in the sense that null is allowed. I would be allowed to call method(null, $param). method($param) would not be legal. In the implementation, all optional parameters before the last mandatory parameter would be required to be specified by the caller but allowed to be null. I don't believe the argument that a parameter should be allowed to be optional but not allowed to be specified as null. If I'm allowed to leave out the argument entirely, it doesn't do any harm to give me 2 ways to say I'm leaving out the argument: one by actually not providing an argument and the other by providing a null. There is a subtle difference, but it is a difference that is already difficult make use of in php without func_get_args (not that that's a bad thing). $.02 (well, less than that) - Todd -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Type hints with null default values
People keep calling the following invalid: function method(MyClass $param1=null, $param2) I'm way behind the times (running 4.3.6), but take a look at how 4.3.6 behaves!: ? function method($param1=null,$param2) { print $param1:$param2\n; } method(1,2); method(1); ? produces 1:2 Warning: Missing argument 2 for method() in /tmp/badopt.php on line 2 1: Notice: Undefined variable: param2 in /tmp/badopt.php on line 3 *** *** Perfect! PHP already accepts =null before a mandatory *** parameter and already knows not to use the null as a *** default value if a mandatory parameter follows! That's *** exactly what you want for the type hint that allows null *** case. *** - Todd On Tue, 2004-10-19 at 10:29, Todd Ruth wrote: On Tue, 2004-10-19 at 02:42, Christian Schneider wrote: The only restrictions I see is that it makes the parameter optional as well (something I don't consider a problem as it is probably desirable in most cases anyway to be able to leave out an explicit null) and that it only works if no mandatory parameter follows, e.g. function method(MyClass $obj = null, $mandatory); is not possible. Not a real problem either IMHO. Is it an implementation difficulty that makes that example not possible? If not, I don't see a problem with it. It just means the first parameter is optional in the sense that null is allowed. I would be allowed to call method(null, $param). method($param) would not be legal. In the implementation, all optional parameters before the last mandatory parameter would be required to be specified by the caller but allowed to be null. I don't believe the argument that a parameter should be allowed to be optional but not allowed to be specified as null. If I'm allowed to leave out the argument entirely, it doesn't do any harm to give me 2 ways to say I'm leaving out the argument: one by actually not providing an argument and the other by providing a null. There is a subtle difference, but it is a difference that is already difficult make use of in php without func_get_args (not that that's a bad thing). $.02 (well, less than that) - Todd -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] return NULL by reference
Unless the problems mentioned in the email I've quoted below have been fixed, be glad to be getting an error message. :) In the past it was quite painful to find all of the places where non-variables were used as references. A big thank you to whoever added the error message! Due to the lack of reproducability, I never filed a bug report for the crashes and corruptions I experienced. Do any of the experts out there know if the underlying problems have been addressed? Thanks! Todd On Thu, 2004-04-08 at 18:53, Todd Ruth wrote: I'm not sure if it caused any of the issues either of you spoke of, but I can report that PHP does have some pointer problems. I've been putting off this email until I had written up something nicer, but it's probably better to just get the word out (assuming this isn't already known)... PHP has problems related to using a temporary as the source for a reference. An obvious no-no is to write $x = NULL; or $x = @$y[5];. These are parse errors. On the other hand, PHP won't complain about: function f() { $y = array(); return @$y[5]; } $x = f(); It even acts OK. The above code could be a mistake or it could be a misguided attempt at optimization (believing that keeping a ref to a temporary is better than setting $x equal to the temporary). Maybe there was a desire to modify $y if applicable, but otherwise be OK with modifying a temporary. In any case, if you have a large enough system and code like that lying around, there's a good chance you'll get crashes. You may not get a crash but instead see unrelated data mysteriously changed in functions that get called later. There are at least 2 ways to adjust the code above to make PHP happy. One is to remove the in the assignment. Another is to create a real temporary variable instead of letting PHP make its own temporary. ie function f() { $y = array(); $temp = @$y[5]; return $temp; } $x = f(); I've had crashes go away and mysterious data overwrites go away with the only change to the system being replacing a piece of code like the first block of this email with a piece of code like the second block. This has happened for just about every kind of = temp you can think of. Here are a few examples (in addition to the case above) of using temporaries as sources for references. I think we've had a crash / mysterious data overwrite for just about all of these (if not all). function f1() { $y = 5; return $y; } $x = f1(); // Get rid of the or add an to f1 function f2() { return NULL; // Get rid of below or use $r = NULL; return $r; } $x = f2(); function g() { return NULL; } function h($x) { $x = 5; } h(g()); That last one could use some combination of the above recommendations to be fixed. For the record, I agree that there are few (if any) cases where the above code is the best code for a design problem, but I also dislike that these code blocks can lead to crashes / corruptions. BTW, we have never had a problem with using a temporary reference as the source for a non-reference copy. That is to say the following has never caused us a problem: function f() { $y = 5; return $y; } $x = f(); Best of luck, Todd -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] GOTO operator
Something doesn't quite seem right to me about a position that has both of the following assertions: 1) goto should not be available 2) there's already an equivalent of goto available, so goto is not needed (and it's just fine that people use the equivalent) If you really believe 1, shouldn't you be arguing for some sort of a warning if someone uses 2? If you really believe it's OK for people to use the equivalent, wouldn't you rather have people use a method of expression that more clearly states their intentions? I heard a story of someone who was extremely proud of a language he/she had written because it only had for and not while (or vice versa). The argument was that it was so much clearer to have a single construct and anything that can be done with one can be done with the other. Do the people supporting position 2 regret having both for and while? I think most programmers appreciate the ability to express themselves with the full vocabulary of standard constructs (even if some of them don't get used very often). Whether goto gets added or not, I hope it is for a consistent set of reasons. - Todd -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] GOTO operator
Actually, the equivalent I meant was the example someone posted of do { f(); break; g(); } while (0). I believe the goto being discussed is a local goto, so just about anything you could do with it can be done today with some sort of ugly while/do/for sort of structure. Someone who would use goto poorly is a strong candidate for making a difficult to read loop. Perhaps it would be better to read a goto in their code than have to figure out why they have that odd loop construct... - Todd On Fri, 2004-07-30 at 11:48, Zeev Suraski wrote: At 21:37 30/07/2004, Todd Ruth wrote: Something doesn't quite seem right to me about a position that has both of the following assertions: 1) goto should not be available 2) there's already an equivalent of goto available, so goto is not needed (and it's just fine that people use the equivalent) If you really believe 1, shouldn't you be arguing for some sort of a warning if someone uses 2? You have a point, but it's not that strong. It's much more difficult to abuse exceptions, both because of their interface which only suits error handling (you'd find it difficult to implement loops with exceptions, for instance), because you have to learn how to use them from docs (you won't be able to guess you way around it like you could with GOTO), and because of the name that doesn't leave any room for mistakes, that it's designed for handling error situations. Zeev -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] what happened to that new isset() like language
That would satisfy some of the requested feature, but try calling ifsetor($my_array['bad key'], functionWithSideEffects()). Marcus has repeatedly mentioned that the requested feature is hard (bordering on impossible) to implement, but in the requested feature (if I understand it (and it is what I would ask for too :) )), there would be no error for using a key that isn't in the array, there would be no side effect of creating a key in the array, and if the $my_array['bad key'] actually did happen to be non-NULL, the function with the side effects wouldn't get called. That would be really handy, especially if it could take a variable number of arguments. Using a standard name like coalesce would be nice. BTW, I have no weight around here; just thought I could help clarify, having following this thread with interest... - Todd On Fri, 2004-07-09 at 12:07, Cris H wrote: Isn't this problem solvable with just a User Space function? ?php error_reporting(E_ALL); function ifsetor($variable, $alternate = NULL){ if(isset($variable)){ $tmp = $variable; echo('p$variable exists./p'); } else{ $tmp = $alternate; echo('pno $variable here./p'); } return $tmp; } // no errors thrown ... $nonexistent = ifsetor($nonexistent); ifsetor($randomNonexistent); if($nonexistent !== NULL) echo('p$nonexistent is NOT NULL/p'); else echo('p$nonexistent is NULL/p'); ? Because, as Derick Rethans mentioned, arguments passed by reference will not trigger the Undefined (variable | index) Notice at the point of the function call, and also PHP's C++ style default arguments providing the alternate value, surely the above code would suffice? Apologies if I've completely misunderstood (with certainty a non-zero probability)... Regards, Cris ___ALL-NEW Yahoo! Messenger - so many all-new ways to express yourself http://uk.messenger.yahoo.com -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Construct Request
You can avoid the E_NOTICE using a reference, but it can have undesired side effects. For example, if you pass $x[5] by reference (whether to an internal function or a user defined function), $x[5] will be created and set to NULL. To avoid this side-effect, don't use the reference and instead use @$x[5] as the first argument to the function. (but DO NOT use @$x[5] as an argument to a function that takes a reference - it may cause a crash/corruption later.) - Todd On Thu, 2004-04-15 at 13:14, Jason Garber wrote: I wrote this (I underlined the relevant parts for you): You'll need something more clever, because an undefined key 'CUST_ID' in $_POST['CUST_ID'] will strill throw a Consider this: --- ?php error_reporting(E_ALL); function setor($param, $default) { return (isset($param) ? $param : $default); } $x = setor($x, 10);///Should Produce an E_NOTICE echo gettype($x) . ':' . $x . \n; ? --- This DOES NOT produce an E_NOTICE like you said (notice the ). However, $param1 is defined and NULL inside the function, even though $x was not a defined variable outside the function?? ~Jason -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
[PHP-DEV] Access Violations / Corruptions / Refs to temps
I have a feeling that PHP has a memory problem somewhere :/. I'm not sure if it caused any of the issues either of you spoke of, but I can report that PHP does have some pointer problems. I've been putting off this email until I had written up something nicer, but it's probably better to just get the word out (assuming this isn't already known)... PHP has problems related to using a temporary as the source for a reference. An obvious no-no is to write $x = NULL; or $x = @$y[5];. These are parse errors. On the other hand, PHP won't complain about: function f() { $y = array(); return @$y[5]; } $x = f(); It even acts OK. The above code could be a mistake or it could be a misguided attempt at optimization (believing that keeping a ref to a temporary is better than setting $x equal to the temporary). Maybe there was a desire to modify $y if applicable, but otherwise be OK with modifying a temporary. In any case, if you have a large enough system and code like that lying around, there's a good chance you'll get crashes. You may not get a crash but instead see unrelated data mysteriously changed in functions that get called later. There are at least 2 ways to adjust the code above to make PHP happy. One is to remove the in the assignment. Another is to create a real temporary variable instead of letting PHP make its own temporary. ie function f() { $y = array(); $temp = @$y[5]; return $temp; } $x = f(); I've had crashes go away and mysterious data overwrites go away with the only change to the system being replacing a piece of code like the first block of this email with a piece of code like the second block. This has happened for just about every kind of = temp you can think of. Here are a few examples (in addition to the case above) of using temporaries as sources for references. I think we've had a crash / mysterious data overwrite for just about all of these (if not all). function f1() { $y = 5; return $y; } $x = f1(); // Get rid of the or add an to f1 function f2() { return NULL; // Get rid of below or use $r = NULL; return $r; } $x = f2(); function g() { return NULL; } function h($x) { $x = 5; } h(g()); That last one could use some combination of the above recommendations to be fixed. For the record, I agree that there are few (if any) cases where the above code is the best code for a design problem, but I also dislike that these code blocks can lead to crashes / corruptions. BTW, we have never had a problem with using a temporary reference as the source for a non-reference copy. That is to say the following has never caused us a problem: function f() { $y = 5; return $y; } $x = f(); Best of luck, Todd -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Adding a few debug helpers to php4.x
Thanks for the replies. First, in response to Stefan... [EMAIL PROTECTED]:~$ php -r '$a = 2; $b = $a; debug_zval_dump($a);' long(2) refcount(3) [EMAIL PROTECTED]:~$ I missed that one. Thanks! With that I'd at least be able to implement ref_count in php. And then in response to Adam... (dis)allow_copies(mixed var) What about implementing this directly in php? You could use trigger_error in the constructor to stop the script from executing if the object is instantiated more than once. I'll end up doing both. I'll do what you've mentioned to get an error from the following code: $s1 = new Singleton(); // Constructor sets non-member var to true $s2 = new Singleton(); // The constructor will fail I need disallow_copies() also though in order to get an error from the following code: $s1 = new Singleton(); // constructor calls disallow_copies($this) $s2 = $s1; // With php4 I get a copy without any function call or the following code: function f($server) { // Bug! Should have been $server ... } $s1 = new Singleton(); // constructor calls disallow_copies($this) f($s1); // With php4 I get a copy without any function call Finding those bugs when you have tens of thousands of lines of php can be a real headache. That's why I'd very much like a disallow_copies function. Is anyone familiar with the extent of the uninitialized struct issue I faced with the implemention I posted yesterday? Thanks again, Todd -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Adding a few debug helpers to php4.x
Actually, I found the code reasonably clear - a kudos to someone. The points about the footprint and performance are well taken. Because the feature is most important before any customers see the latest rev of product, the feature would be just as useful as an optional part of the php build. It's already useful to do testing with a different php build than the production build just to have php debugging enabled. Although the feature performs best with an added field in the zval struct, if it is considered bad form to have an ifdef in the struct, the feature could be implemented with a separate table. (The table would have zval pointers as indices and allow_copies values as values. Any pointer not in the table would be assumed to have allow_copies set to true. The table, checks, and new functions would only be avaiable for debug builds (or whatever build flag is most appropriate).) Better? - Todd On Wed, 2004-03-03 at 12:54, Andi Gutmans wrote: At 09:25 PM 3/3/2004 +0100, Derick Rethans wrote: On Wed, 3 Mar 2004, Todd Ruth wrote: Finding those bugs when you have tens of thousands of lines of php can be a real headache. That's why I'd very much like a disallow_copies function. But as you demonstrated with your patch you need to modify some of the basic data types that PHP uses and thus increasing memory footprint and decreasing performance. It is therefore very unlikely that this will be ever allowed into the PHP source. Yep, I agree with Derick. Needless to say that it's very dangerous to try and make sense out of the low level stuff the engine and the PHP extensions are doing (such as copy constructing, separating and other stuff). Andi -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
[PHP-DEV] Adding a few debug helpers to php4.x
; } ZVAL_ALLOW_COPIES(*arg) = 0; } /* }}} */ PHP_FE(disallow_copies, first_arg_force_ref) In zend.h: struct _zval_struct { /* Variable information */ zvalue_value value; /* value */ zend_uchar type;/* active type */ zend_uchar is_ref; zend_ushort refcount; zend_bool allow_copies; /* NEW NEW NEW */ }; #define ZVAL_ALLOW_COPIES(pz) ((pz)-allow_copies) #define INIT_PZVAL(z) \ (z)-allow_copies = 1; /* NEW NEW NEW */\ (z)-refcount = 1; \ (z)-is_ref = 0; In zend.c: zval_used_for_init.is_ref = 0; zval_used_for_init.refcount = 1; zval_used_for_init.allow_copies = 1; /* NEW NEW NEW */ zval_used_for_init.type = IS_NULL; In zend_variable.c: ZEND_API int _zval_copy_ctor(zval *zvalue ZEND_FILE_LINE_DC) { /* This is a notice instead of error because of the issue discussed below */ if (!zvalue-allow_copies) { zend_error(E_NOTICE, Cannot copy value for which allow_copies is false); } ... Whew! This email is a lot longer than I realized it would be and I'm only just now getting to the problem. Hopefully, at least a couple of people are reading this part. In theory, the code above should be a complete implementation of the feature. In practice, I found that a lot of the code in php doesn't initialize the variables used. That may be fine for a particular piece of code that only relies on a couple of members of the struct, but it makes it hard to add functionality later. Here's an example from my notes of part of my effort to fix this: Replace any call to ALLOC_ZVAL(z) that is not immediately followed by a line of the form *z = whatever or INIT_PZVAL(z) with ALLOC_INIT_ZVAL(z). vi `find . -name *.[hc] | xargs grep -l 'ALLOC_ZVAL'` That helped and so did initializing the 5 cases of bare zend_constant variables and the many bare znode variables, but eventually I gave up tracking down every last piece of code that lacked initialization. If I was on the tip with a cvs account, I would have at least felt it was worthwhile. (Who knows; maybe uninitialized values are contributing to bugs in php...) As it was, it was a throw-away effort. My boss suggested keeping a separate table instead of adding to the zval struct and just ignoring the cases in which an unitialized zval is looked for in the table. We agreed that isn't as clean and has worse performance. We also agreed that the best course is to write to the php development community for guidance. So... any thoughts? Thanks! Todd Ruth -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php