[PHP-DEV] Re: New RFC draft static class constructor
Am 13.04.2015 um 15:37 schrieb Johannes Ott: Hi, finally I managed to do my first RFC draft. https://wiki.php.net/rfc/static_class_constructor I hope I have done everything correct so far and I'm looking forward to your feedback on it. As I already mentioned in the prediscussion thread here: For being my first change to the PHP core, I would be very happy, if someone of the old stager would help me with the implementation of this RFC if it is accepted. Regards Hi there, there was a really bad situation in my life the last week, so I'm not able to do anything on this Draft for some days, I will pause it for some weeks now Regards -- DerOetzi -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] New RFC draft static class constructor
Am 14.04.2015 um 00:16 schrieb Levi Morrison: - IMO, the method should be called when the class is created, just after every parent class and implemented interfaces are created. In general I think static class data and static class constructors are a sign of poorly designed code, which means I am against this feature. Thanks for the flowers as we would say in Germany! I didn't hear I'm doing poor code for a long time now :( -- DerOetzi -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV][RFC-DRAFT] New RFC draft static class constructor
As the RFC is still in draft status, I will stop for now answering any issues on the purpose of this RFC. I will now rewrite some things at the draft, and come back to the discussion in this threads after those changes I will focus on the following open issues I have identified during the last two days discussion here. I identified the follwing issues to clearify more: - Magic method vs. static block (as it is done by JAVA) - Naming of the method - Why the trigger should be like it is proposed by the RFC And I will focus again on the contra arguments during last days discussion and the pre-draft discussion some weeks ago. In my point of view all of those arguments I read so far can be summarized to the single argument: You should avoid static class state and for this a initialization method, because this is poor designed code and crucial things can be done with it. Please feel free to correct me, if I got anyone's argument against the RFC wrong! I hope I can finish the changes to the drafts during the weekend, afterwards I will answer your comments just by linking to the specific RFC-Section. Thanks and regards -- DerOetzi -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] New RFC draft static class constructor
Am 14.04.2015 um 16:33 schrieb Dan Ackroyd: Here is some feedback then: From the RFC: - Trigger for “magic” method call: First call to class, either first call to __construct(...) or first call to any public or protected static method or property of the class I don't think this doesn't cover all cases that it needs to. For example calling unserialze on some data that results in a class that has this static initializer should mean that it would be invoked? Similarly ReflectionClass::newInstanceWithoutConstructor also creates a class in a way that isn't covered in the RFC, but presumably should be. Your correct I forgot this two scenarios of first calls to a class. Thanks for the hint! But in the new draft (v0.4) I'm preparing at the moment I'll try to formulate the trigger first call more common by comparing it to the same trigger for __autoload function. Then these two scenarios should be included as well. From the RFC. the static class constructor should be able to throw a catchable Exception for user error handling, if it is not possible to initialize. The open issue for me is, what the behavior on recalling the static class constructor afterward is. There are two possible behaviors I do not know which one I really would prefer so far. You missed the third and in my opinion correct one; the static initializer would only ever be called once. I think this is suggested behaviour 1, isn't it? On recall of the static class constructor a fatal error is raised to ensure it is only called once... If the programmer catches the exception and forces the program to continue, that is their own problem. Adding complexity to a language to try to work around programmers ignoring exceptions is not a good idea. I agree to this point that ignoring an exception is a bad idea. I think the example-code is a bit confusing, because the empty catch-block gives the impression that the exception is ignored. But what is really meant by behaviour 2 is that the programmer has the opportunity to handle the exception not by exiting his programm, but by cleaning up the situation and afterwards retry the code which failed before. I will try to clearify this in one of the next draft versions. I think the RFC needs to be clearer in the specification of the order that static initialization is called in. e.g. class B extends class A. Both A and B have static initialization blocks. When a user calls `new B()` which static initialization block is called first? While rewriting the draft for v0.4 I although noticed this gap inside specification and came to the conclusion that this is the third first call scenario I haved missed. Because inheritance by using keyword extends is already a first call to class A. cheers Dan Thanks for really constructive feedback, that one really helps me for the next draft of rfc Regards -- DerOetzi -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] New RFC draft static class constructor
Am 13.04.2015 um 18:54 schrieb Johannes Schlüter: On Mon, 2015-04-13 at 17:23 +0200, Johannes Schlüter wrote: Why am I saying it makes the language more complex? - Your proposal seems to miss mentioning when exactly the method is executed. what is Ah, I missed this Trigger for “magic” method call: First call to class, either first call to __construct(...) or first call to any public or protected static method or property of the class Which means adding a flag, which has to be checked on every method call or other access to *any* class and leads to completely random (from perspective of average user) behavior while this feature can't be used for an obvious task like registering itself as plugin into some registry. -1 johannes The obvious task is to initial the state of the class before usage as I wrote inside my introduction of the RFC. I think there is no random behavior (not more then other so called magic methods). But I see that I forgot this point in the discussion part because we already had this point on the prediscussion. Will add this tomorrow, with my exact answer to this point, Thanks for reminder. https://wiki.php.net/rfc/static_class_constructor -- DerOetzi -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
[PHP-DEV] Re: New RFC draft static class constructor
Am 13.04.2015 um 18:48 schrieb Cesar Rodas: Instead of having a method, why don't we allow body expr to be evaluated as we see things in the Class definition? ?php class foobar { static protected $conn = new mysqli('localhost', 'my_user', 'my_password', 'my_db'); } It's cleaner but it breaks compatibility with everything :-( -- César D. Rodas Open Source developer +595-983-161124 PGP: F9ED A265 A3AB C8A1 D145 7368 158A 0336 C707 0AA6 Hello César, you accidently wrote this answer only to me, so I forward this to the mailing list together with my answer. First of all I would not store any resource handle, like a mysql connection you did in your example, directly to a static member. (Will add another point on this to the discussion-section the next days) https://wiki.php.net/rfc/static_class_constructor#discussions Second point is that with your suggested syntax only single methods can be used to initialize the static member. With my proposal you will be able to do more complex initialization algorithms. For example open a config-file with fopen, read the content to a static member and close the config-file again with fclose. Regards -- DerOetzi -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
[PHP-DEV] New RFC draft static class constructor
Hi, finally I managed to do my first RFC draft. https://wiki.php.net/rfc/static_class_constructor I hope I have done everything correct so far and I'm looking forward to your feedback on it. As I already mentioned in the prediscussion thread here: For being my first change to the PHP core, I would be very happy, if someone of the old stager would help me with the implementation of this RFC if it is accepted. Regards -- DerOetzi -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Re: Request for RFC karma
Am 10.04.2015 um 20:57 schrieb Ferenc Kovacs: On Fri, Apr 10, 2015 at 6:07 PM, Johannes Ott m...@deroetzi.de wrote: Am 10.04.2015 um 17:54 schrieb Christoph Becker: Johannes Ott wrote: Am 13.03.2015 um 16:42 schrieb Johannes Ott: as you can see at the initial discussion thread with the subject static constructor I'm planing to do a Draft for a RFC for the suggested feature. How do I get the karma to create this RFC on wiki? nearly a month ago I requested for RFC-karma. Did I do something wrong in process? Thx for answers I suggest you try to register once more with the same user name. There have been some problems with regard to the Wiki registration, which should have been resolved in the meantime. If the user is already registered (even without account approval), you should get a respective message. Afterwards write to this list again mentioning your username, please. -- Christoph M. Becker Thanks for answer I have a valid loginname deroetzi which I can use to login. So I request again for RFC-Karma to post my RfC static constructor thanks -- DerOetzi -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php I've just granted you with rfc karma. Thanks! -- DerOetzi -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] New RFC draft static class constructor
Am 13.04.2015 um 17:29 schrieb Benjamin Eberlei: What would happen if you call the parent constructor: class A extends B { static public function __static() { B::__static(); } } Please have a closer look to the definition of the function: https://wiki.php.net/rfc/static_class_constructor#proposal it should be declared private to prohibit any access from outside the of the class itself. Although see the the answer 2 in discussion section: https://wiki.php.net/rfc/static_class_constructor#inheritance_of_the_class_constructor Thanks for feedback On Mon, Apr 13, 2015 at 5:23 PM, Johannes Schlüter johan...@schlueters.de wrote: Hi, On Mon, 2015-04-13 at 15:37 +0200, Johannes Ott wrote: finally I managed to do my first RFC draft. https://wiki.php.net/rfc/static_class_constructor I hope I have done everything correct so far and I'm looking forward to your feedback on it. In my opinion this makes the language way more complex as there are more places which suddenly execute code but solves a small problem compared to that. (Which actually is an issue many people would suggest to avoid completely instead of ennobling this with a language feature. Why am I saying it makes the language more complex? - Your proposal seems to miss mentioning when exactly the method is executed. what is the output of a.php: ?php echo 'A: '.__FILE__.':'.__LINE__.\n; class A { static function __static() { echo __CLASS__.'::'.__METHOD__.\n; } } echo 'B: '.__FILE__.':'.__LINE__.\n; class B { static function __static() { echo __CLASS__.'::'.__METHOD__.\n; } } echo 'C: '.__FILE__.':'.__LINE__.\n; ? b.php: ?php echo 'D: '.__FILE__.':'.__LINE__.\n; C::$foo = 23; echo 'E: '.__FILE__.':'.__LINE__.\n; include 'a.php'; echo 'F: '.__FILE__.':'.__LINE__.\n; class C { static $foo = 0; static function __static() { echo __CLASS__.'::'.__METHOD__.\n; } } echo 'G: '.__FILE__.':'.__LINE__.\n; class D extends B { static function __static() { echo __CLASS__.'::'.__METHOD__.\n; } } echo 'H: '.__FILE__.':'.__LINE__.\n; ? Mind that in b.php we make use of class C above the declaration, which we can do as C is a simple class and can be bound early during compilation. Class D however can only be bound during run-time, after including a.php, which happens after C was already used. johannes -- DerOetzi -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] New RFC draft static class constructor
Am 13.04.2015 um 18:02 schrieb François Laupretre: De : Johannes Ott [mailto:m...@deroetzi.de] finally I managed to do my first RFC draft. https://wiki.php.net/rfc/static_class_constructor I hope I have done everything correct so far and I'm looking forward to your feedback on it. Interesting. It also allows to respect PSR-1, which says 'Files SHOULD either declare symbols (classes, functions, constants, etc.) or cause side-effects (e.g. generate output, change .ini settings, etc.) but SHOULD NOT do both' (see https://github.com/flaupretre/automap/blob/develop/src/classes/Automap.php for an example). Comments : - __static is ambiguous and does not reflect the method's role. Even if longer, I definitely prefer __staticInit or, even better, __classInit. Okay I will think about the alternative names, I somehow like __classInit you proposed or __classConstruct - IMO, the method should be called when the class is created, just after every parent class and implemented interfaces are created. If some load a bunch of classes they don't use, that's their problem, not ours. It is not a reason to follow a two-step process. A properly written program uses autoloading and loads the classes it needs only. Another argument is that I'm not sure it is possible to catch every case of read access to static properties. On the one hand I think we should respect most of the user-land code as far as possible and on the other hand I think there should be the possibility to handle the being initialized or not initialized inside the class action. - I think you should provide a destructor method because there can be a need to cleanup/close the resources opened when initializing the class. It can be open files, sockets, or any other resource, but, IMO, they need to be explicitly closed when the request ends. Please see my answer 4 in discussion section for this: https://wiki.php.net/rfc/static_class_constructor#need_of_a_class_destructor_to_handle_unload_order_dependencies Regards François -- DerOetzi -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] static constructor
Am 15.03.2015 um 11:02 schrieb Crypto Compress: I think I now get the misunderstanding I had on your destructor question Sorry for confusion. My points are agnostic about implementation details and concrete code. It's up to ppl to use this feature as they like. Okay get your point, but as already discussed several times, the rfc should not be declined for the reason a ppl, who doesn't understand when to use static context or when not to use at all, can do crucial things. Because he although can do without the static constructor. For a horiffic example: class Example { private static $handler; public function open() { self::$handler = fopen('example.txt'); } ... } Example::open(); Indeed I have the opinion some beginner who is doing such horiffic code maybe think more about what he is doing and especially about the side effects inside a so called magic method, then outside. - first point is a logical conclusion: If there is a cctor, there should be a cdtor. Okay the logical conclusion I can take in count. But doing 15 years of OOP-programming now, I never had the need to have a cdtor, for a valid usage of static context. And still after I have seen your examples, which should all be done, as I explained, with instances instead of direct static binding, I don't see the use case for a cdtor. - second point is about implicit order: Shutdown process will free in reversed creation order. Classes don't have guaranteed creation order. But I hope shutdown process of PHP is as intelligent not do unload a class which is needed in another class before this class?! Regards, -- DerOetzi -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] static constructor
Am 13.03.2015 um 01:33 schrieb Christoph Becker: Johannes Ott wrote: And i although see no DI or Singleton pattern to use here to get the same functionality, if you want to use like Config::getHostname() and not like Config::getInstance()-getHostname() which is really unnecessary abstraction level for nothing in my opinion! It is possible, however, to add static wrapper methods to access the singleton's methods, like public static function getHostname() { return self::getInstance()-_getHostname(); } It is not only about the extra method-call but although the additional Null check inside this method call. Let's do some calculation for that: in average I have 5 calls of the logger per method the message is used 10 times during the programm. Now we already have 49 unnecessary method calls (with all needed to do for the interpreter like preparing stack, copying the returns etc.) and 40 unnecassary null checks inside (as we agreed before that is not counted fully, because the evaluation of the flag will although take some time but can be more efficient inside the interpreter). Let's now think only about 10 such methods we are already at a count of 490 unnecessary method calls. Maybe only slightly worse performance but it is a performance issue! And there is this very old performance rule: a lot of small performance issues can become quickly to a huge one. I have counted the calls in code of self::$LOG- inside one small private webproject of mine with less logging implemented yet. But there are already 128 calls. If you multiply by 10 you already have 1280 calls on runtime, I think that is a performance issue. It seems to me that the logger example is not appropriate to show performance penalties due to unnecessary method calls and null checks, because the actual task of the logger (write to a file/database, or even send an email) is easily much more demanding performance-wise. Anyhow, in my humble opionion, there had been enough initial discussion on this idea, and it would be reasonable to proceed with the actual RFC. See How To Create an RFC[1] and especially The Mysterious PHP RFC Process and How You Can Change the Web[2]. :) [1] https://wiki.php.net/rfc/howto [2] https://blogs.oracle.com/opal/entry/the_mysterious_php_rfc_process I tried to get some RFC karma for my wiki account, following those lines: Email internals@lists.php.net requesting RFC karma for your wiki account. In the email, remind people about the RFC you plan to create. Note that RFC karma does not automatically give you karma to vote. See https://wiki.php.net/rfc/voting#rfc_proposer I didn't get any reaction on my mail for three days, is this normal or have I done something wrong? Thanks for your help Regards, -- DerOetzi -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] static constructor
Am 15.03.2015 um 19:47 schrieb Rowan Collins: On 15/03/2015 10:41, Johannes Ott wrote: Okay get your point, but as already discussed several times, the rfc should not be declined for the reason a ppl, who doesn't understand when to use static context or when not to use at all, can do crucial things. Because he although can do without the static constructor. For a horiffic example: class Example { private static $handler; public function open() { self::$handler = fopen('example.txt'); } ... } Example::open(); Indeed I have the opinion some beginner who is doing such horiffic code maybe think more about what he is doing and especially about the side effects inside a so called magic method, then outside. I'm not clear what's so different between this and your logger example. Here you have a file handle, which in PHP happens to be a special type rather than an object, and are storing it in a static property; closing the file handle has to be managed somehow, and this code is letting PHP do this implicitly with what amounts to a destructor on the file handle resource. The difference is as I told the Resource Handler is wrapped inside a Singleton Instance with a destructor! I never ever would store any kind of resources (opening any kind of connections to db, file, socket etc.) directly to the static context without wrapping in a instance, because those are really dynamic handles which need a proper constructor and destructor for the special connection. However many intermediate instances you create, at some point the destructor has to run, and that will only happen once the static reference is unset. Luckily, the Zend Engine will go through and garbage collect all global and static variables at the end of a request, so you can cheat that way. I think that is no kind of a cheat, in my opinion this is the normal behavior how static stored properties and instances, stored at them, should be cleanup in every oop-language. Or, you can *invalidate* the objects, rather than destructing them, as implied by your DBAdapter::closeAllConnections() example - there will still be references to those connections live in your code if, for instance, you have Example::$logger, and $logger-dbConnection. You can't have an Example::cleanupResources() method, because it would fire the static constructor on pages which hadn't used the class yet, destroying the lazy-loading. You always talking about the singleton-pattern, as I although told different times now, I have no resources directly stored in static context but in singleton instances inside. for example the DBAdapter::closeAllConnections(): public static closeAllConnections() { while(count(self::$connections) 0) { self::$connections[0]-close(); unset(self::$connections[0]); } } the same for LogAdapter. What you're really relying on is that the implicit static destructor provided by the engine is good enough for the kinds of resource which a static constructor should be dealing with. This is also true of many objects, which don't technically need a custom destructor to close file or DB handles, because Zend will reference count the resource, but more advanced objects can do more advanced cleanup. Yes indeed this is true, and again same sentence: resources - inside instances not directly inside static property. Regards, -- DerOetzi -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] static constructor
Am 15.03.2015 um 12:35 schrieb Crypto Compress: You should reread your mails and keep insults to yourself: as already discussed several times ppl, who doesn't understand some beginner who is doing such horiffic code maybe think more about what he is doing doing 15 years of OOP-programming I never had the need valid usage as I explained direct static binding PHP is as intelligent Bye! Hi Crypto Compress, Sorry those shouldn't be any kind of insult! If you understand those as an insult I really apologize for that! Maybe I was a bit to hard at argue. Nothing else was my intention, then a discussion about the arguments. And when writing about beginner ppl doing horrific code I didn't meant it personaly to someone special, I'll just tried to take count about Rowans argument, that beginners will have extremly problems with this static context. And PHP is as intelligent, I really think PHP is a very smart language already and I tried to implicit, that it is working already correctly on the problem you have told. As a conclusion I will reread my mails in future, and try to improve my sometime really poor English, and think about everything twice, to avoid more misunderstandings on my argues Sorry again! -- DerOetzi -- DerOetzi -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] static constructor
Am 14.03.2015 um 18:34 schrieb Crypto Compress: So I do not see the need of a explicit class deconstructor, because the language should already react correctly on this issues as I can see so far The language cannot know the order of dependencies and how to destruct them. A dependcy between destructors of instances, which the language have to know by itself that sounds horrific indeed. If one instance has destruction dependcies to other instances, you should have used any kind of linking pattern between this instances so the __destruct of the first instance destructed can handle the destruction dependcies. At the moment I cannot think about any use case, where this should be done another way. Maybe you have a concret example for me, so I can think about this? a) Implicit order of dependencies: Logger should be the last destructed DatabaseLogger before FileLogger before error_log-Logger... b) How to destruct: Write Bye! before closing socket. On destruction/unload of a class the language should be able to unset static properties in random order for this reason, without any need of a class destructor?! Reverse creation order. Sorry for replying to myself, but I'm just preparing the RFC and while reading the complete thread again. I think I now get the misunderstanding I had on your destructor question and want to clear that: In your examples you employ some external resources in cctor (e.g. logger, db, ini-files). Do you intend to propose a cdtor to release this resources? I never ever would store any kind of resources (opening any kind of connections to db, file, socket etc.) directly to the static context without wrapping in a instance, because those are really dynamic handles which need a proper constructor and destructor for the special connection. If I use inside the static constructor only for reading purpose and have to ensure that they are closed again. This can be done directly inside the static constructor or in case of my DBAdapter holding the DBConnection instance at the very end of my application. For example class Example { private static $dataFromFile; private static $dataFromDB; private static $localReferenceToLogger; private static function __static() { //Read from file $fHandle = fopen('example.ini', 'r'); self::$dataFromFile = fread($fHandle, 1024); fclose($fHandle); //Shorted DB Example self::$dataFromDB = DBAdapter::readFromDB(); //Get local Reference to logger instance; self::$localReferenceToLogger = LogAdapter::getLoggerInstance(self::class); } } //Somewhere at the end of my application DBAdapter::closeAllConnections(); Hope I could get some light to the problem you meant? Regards, -- DerOetzi -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] static constructor
Am 14.03.2015 um 18:34 schrieb Crypto Compress: So I do not see the need of a explicit class deconstructor, because the language should already react correctly on this issues as I can see so far The language cannot know the order of dependencies and how to destruct them. A dependcy between destructors of instances, which the language have to know by itself that sounds horrific indeed. If one instance has destruction dependcies to other instances, you should have used any kind of linking pattern between this instances so the __destruct of the first instance destructed can handle the destruction dependcies. At the moment I cannot think about any use case, where this should be done another way. Maybe you have a concret example for me, so I can think about this? a) Implicit order of dependencies: Logger should be the last destructed DatabaseLogger before FileLogger before error_log-Logger... Okay the Implicit order for class unload should be safe, if you use the Logger classes inside class A and class B, PHP should unload the class Logger as last one after A and B. The unload order of DatabaseLogger before FileLogger is a internal of the Logger Instances as Logger itself is a singleton Factory: For example: class LogAdapter { private static $instances = []; public static getLoggerInstance($classname) { if (!array_key_exists($classname, self::$instances)) { self::$instances[$classname] = new Logger($classname); } return self::$instances[$classname]; } } class Logger() { ... public __destruct() { //Unload whatever you need. } } b) How to destruct: Write Bye! before closing socket. To manage a socket connection is not a typical use case for a global static class context because normal use case of a Socket class is to manage different Sockets. So this is typically a instance pattern to use, where the __destruct() can say bye. On destruction/unload of a class the language should be able to unset static properties in random order for this reason, without any need of a class destructor?! Reverse creation order. The random was just meant as placeholder for the fact that for static properties it should not matter in which order they are unset by the language. Can be reverse creation order or something else. Regards -- DerOetzi -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
[PHP-DEV] Re: [RFC][PRE-VOTE] Reserving More Types in PHP 7
Am 14.03.2015 um 06:41 schrieb Levi Morrison: RFC Link: https://wiki.php.net/rfc/reserve_more_types_in_php_7 The proposal has changed from the original. It no longer reserves the aliases out of the interest of reserving the smallest useful, uncontroversial subset. Some people want to remove aliases for these types so in the interest of being as uncontroversial as possible I am no longer proposing to remove them. This will go into voting on March 15th unless something comes up between now and then to persuade me otherwise. Sorry but I'm strictly against reserving any aliases, without directly implementing some functionality behind them. This will block any user-land workarounds for doing those features, while they maybe will implemented versions after this reservation by the language itself. That is no well behavior of a language. For this reason -1 vote for me having some kind of Scalar Autoboxing objects already implemented. Yes I would be able to rename for example int object to MyInt but then I have to refactor all usages and have to refactor again if the feature is finally in. Regards, -- DerOetzi -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] static constructor
Am 14.03.2015 um 07:49 schrieb Crypto Compress: Am 13.03.2015 um 11:30 schrieb Johannes Ott: Am 13.03.2015 um 07:45 schrieb Crypto Compress: Hello Johannes, in other mails you argue with Rowan about global state. I think it's better to focus on innovation of class context in global scope, as it's impossible to reason the disadvantages of global state away. (Discussions on variable scope are painful too.) And two questions: 1. By definition cctor is guaranteed to be executed only once. Right? Yes as the __static should be as well. See discussion with Rowan and Patrick for details. As I already told, I still have to clearify howto react if an exception occurs inside the static class constructor. I prefer at the moment the variant that a second try will raise a fatal error. But I will think about this before I'll prepare the RFC. 2. In your examples you employ some external resources in cctor (e.g. logger, db, ini-files). Do you intend to propose a cdtor to release this resources? For my understanding the lifecycle of a class is from the loading of the class definition to the end of the application or until some explicit class unload (don't know whether php has such feature). PHP has no explicit class domain unload feature and you do not plan to implement this. Okay. Yes, this could be another RFC in future but not yet. If loading a instance to a static member you must be aware that this instance will live till the end of lifetime of the class (that is the basic of static). But at the end I hope PHP is unsetting all static members as well, which should trigger the destructor of this instance as well. If PHP is not reacting like this (but I'm sure it is because without all suggested singletons here would be a huge memory and connection leak as well), I know what my second rfc would be :D Second point if you open a resource to read some data inside a method and do not assure that it is closed again either explicit inside the method or on a global pattern (for example my DBAdapter I use to read, holds a single connection to database which is closed at the very end of run), this would be poor code inside the static constructor as well as it would be inside every other method. This poor code inside the static constructor seems to be a crucial point of your RFC. As I already told several times, this poor code does NOT depend on a static constructor method. On the one hand the proposed static constructor is only a shorter replacement of several valid user-land patterns doing the same feature already, as you can see on the examples I or Patrick posted in this thread. On the other hand I force the opinion, that a RFC should not be declined for the reason someone, who is not understanding the feature and all of if side-effects, maybe can do some crucial things with it, while it is useful for programmers who know how to use it. Because in my opinion, as I already tried to figure out, you can do crucial things with every single language feature, which is already implemented yet, if you're not knowing how it works and use it anyway. So we should prohibit PHP and all other languages ;) (Just fun!) So I do not see the need of a explicit class deconstructor, because the language should already react correctly on this issues as I can see so far The language cannot know the order of dependencies and how to destruct them. A dependcy between destructors of instances, which the language have to know by itself that sounds horrific indeed. If one instance has destruction dependcies to other instances, you should have used any kind of linking pattern between this instances so the __destruct of the first instance destructed can handle the destruction dependcies. At the moment I cannot think about any use case, where this should be done another way. Maybe you have a concret example for me, so I can think about this? On destruction/unload of a class the language should be able to unset static properties in random order for this reason, without any need of a class destructor?! Regards, Thank you! Regards, -- DerOetzi -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] static constructor
Am 13.03.2015 um 01:33 schrieb Christoph Becker: Johannes Ott wrote: And i although see no DI or Singleton pattern to use here to get the same functionality, if you want to use like Config::getHostname() and not like Config::getInstance()-getHostname() which is really unnecessary abstraction level for nothing in my opinion! It is possible, however, to add static wrapper methods to access the singleton's methods, like public static function getHostname() { return self::getInstance()-_getHostname(); } I really do not understand why everybody here seems to try to use Singleton where ever it is possible. Indeed Singletons are a nice Design Pattern, but they are no universal remedy for every problem just for the fact you can use it there as well. Why are in your opinion static members are not allowed to hold more complexe datastructures then simple scalars? Please give me one valid argument why I should double all of the functions in my code for a static and non-static access beside the argument that I have to use a Singleton. As I already said this is a abstraction level that makes absolutly no sense. It is not only about the extra method-call but although the additional Null check inside this method call. Let's do some calculation for that: in average I have 5 calls of the logger per method the message is used 10 times during the programm. Now we already have 49 unnecessary method calls (with all needed to do for the interpreter like preparing stack, copying the returns etc.) and 40 unnecassary null checks inside (as we agreed before that is not counted fully, because the evaluation of the flag will although take some time but can be more efficient inside the interpreter). Let's now think only about 10 such methods we are already at a count of 490 unnecessary method calls. Maybe only slightly worse performance but it is a performance issue! And there is this very old performance rule: a lot of small performance issues can become quickly to a huge one. I have counted the calls in code of self::$LOG- inside one small private webproject of mine with less logging implemented yet. But there are already 128 calls. If you multiply by 10 you already have 1280 calls on runtime, I think that is a performance issue. It seems to me that the logger example is not appropriate to show performance penalties due to unnecessary method calls and null checks, because the actual task of the logger (write to a file/database, or even send an email) is easily much more demanding performance-wise. This depends on the log-level lot of the calls are debug and traces which are not active in production enviroment. Only a few of them are info, warn or error. But you are right it isn't a perfect example for benchmark the current idea, but as a whole I'm sure to have a slightly performance improvment with this static constructor as well. But anywhere performance was not the main matter of concern of this proposal, but to make the possibility to write cleaner code with less lines. Anyhow, in my humble opionion, there had been enough initial discussion on this idea, and it would be reasonable to proceed with the actual RFC. See How To Create an RFC[1] and especially The Mysterious PHP RFC Process and How You Can Change the Web[2]. :) [1] https://wiki.php.net/rfc/howto [2] https://blogs.oracle.com/opal/entry/the_mysterious_php_rfc_process Okay thanks for the hint I will prepare the rfc on weekend then. BTW for me haven't done c- programming for a long time it would be a joy if someone who has mor experience with PHP-core would help to implement the RFC if it will be voted positive. Or even give me some hints to the structure of the core where to start this. Already did some research on that and I'm thinking somewhere zend_object_handler.c but not sure about this. Thanks in advantage to all for the in my opinion good discussion so far about this issue. Gave me some good hints, where I have to have a closer look, when writing the RFC now. Regards -- DerOetzi -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] static constructor
Am 13.03.2015 um 14:36 schrieb Rowan Collins: Sorry, replying to myself to add a couple of thoughts / clarifications: Rowan Collins wrote on 13/03/2015 11:53: Johannes Ott wrote on 13/03/2015 09:53: Why are in your opinion static members are not allowed to hold more complexe datastructures then simple scalars? Complex data structures, yes (and I see the use of __static in such cases). Architectural logic gluing one class to another (as in your Logger example), no. I think I've come up with a better distinction: *state* belongs in instances, whereas *data* can exist globally. A logger object encapsulates state, so a pointer to one is stateful information; storing that state statically is what feels wrong. I agree with this statement only a bit because it makes static context obsolete: real *states* belong to instances, no doubt about this. The logger state for example as LogAdapter is a Singleton-Factory is still inside the singleton instance and in this case only a new reference to the class specific instance is stored as kind of shortcut for less code and maybe little bit of performance to the class itself. That is although the DI-pattern on runtime, but in static class context. But anyway a class having any kind of static property inside is stateful by definition of static. The best example is already each singleton-class, it has the state initialized or not intialized. That is the basic concept of static-context at all, the only stateless things inside class context are class-constants. Or another example the posted ConfigFile-Wrapper, what is the sense of wrapping another level arround by doing it with a singleton instance. The class itself by its definition already represents the state of config.ini-File that will not change during the current runtime because it is global *data*. In my opinion there is absolutely no sense beside the effect that I have more code to write and especially to read. As conclusion as long as there is this static, stateful class context each coder can decide at everytime which static properties he sets to define the state of the class, as a good programmer you should be aware to use this careful, but that has absolutley nothing todo with the proposed RFC. But while you have already for instances a defined language method called __construct to set the inital state of an instance, there is no such language method to set the initial state of the class, which would be the __static(); In my opinion this would even help beginners to understand how careful they have to be with static context, because they are doing something inside a special magic method. BTW even the singleton pattern could have a slightly better performance with this feature, if you do not have the need of parameters to the instance constructor code can look like this: abstract class Singleton() { private static $instance; private static function __static() { self::$instance = new Object(); } public static function getInstance() { return self::$instance; } } A singleton in this case says there is a bunch of stateful information here, but everywhere *in the current code* needs the same instance of it. Please give me one valid argument why I should double all of the functions in my code for a static and non-static access beside the argument that I have to use a Singleton. You don't need to double all the calls. In fact, the majority of your code should not even know the Singleton is there, because they should be treating it as though they have an instance. At certain key points in your code (constructors, the top of methods) you add $foo = Foo::getInstance();, then all your calls look like $foo-doBar(); That's the way I do it, anyway - treat getting the instance for a singleton like importing a variable from global scope, which is basically what it's doing. In other words, saying Foo::getInstance()-bar(); is like using $GLOBALS['foo']-bar(); saying $foo = Foo::getInstance(); $foo-bar(); is like saying global $foo; $foo-bar(); The act of retrieving the singleton is separate from the act of using it. Regards, I think as Christoph wrote we should now do a cut here for the inital discussion, because we are in a circle now. I will now get on at the RFC process, and will prepare the RFC-draft asap. I will try to summarize as good as possible all discussion points we had the last days here. And I will try to figure out as clearly as possible how each point really touchs the purpose of the new requested language feature or is a general problem if you use static context a wrong way, although outside the static constructor. I want to say thank you especially to you Rowan, for the so far very good discussion, which gives a lot of input to me for writting the RFC. Regards, -- DerOetzi -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
[PHP-DEV] Request for RFC karma
Hi there, as you can see at the initial discussion thread with the subject static constructor I'm planing to do a Draft for a RFC for the suggested feature. How do I get the karma to create this RFC on wiki? Regards, -- DerOetzi -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
[PHP-DEV] Re: A plea for unity on scalar types
Thanks for the clear statement, which lights up the fog a little bit for. Watching out for a scalar typehints feature for round about 10 years without knowing about this internal list, I always was wondering what can be so complicated to implement it, because I already evaluated some different ways how to do this for my thesis. I already thought about a political reason for that. I'm with you that your Dual RFC is the right solution to satisfy the needs of all of the three mentioned groups in my opinion as well. I would give a clear +1 to it, but I don't have any voting karma yet! Regards -- DerOetzi -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Request Feedback for Instance Variable Sugar RFC
Am 11.03.2015 um 17:21 schrieb Rowan Collins: My reasoning is that code that is ambiguous is hard to read. If $foo can mean either a local variable called $foo or a property of the current object called $foo, then you have to know which it is in order to understand what code is doing. So for clean code rules you should do smaller methods if you can't even see clearly whether you declared $foo locally or not. This is not about a strict OOP-world, incidentally, it's about scoping rules. Java imports object properties into the scope of each method, PHP does not. Even if properties had to be declared (which is probably a good idea), local variables still wouldn't be - in Java, the fact that it's not declared locally means it *must* be coming from somewhere else. No if it is not declared locally it doesn't mean it's coming from somewhere else, but it means it is coming from one of the next higher scopes which is normally the Object. I also know that when I was first learning Java at school, it confused me immensely which variables I was allowed to access in static contexts. In PHP, that's simple - if you can't access $this, you can't access any of it's properties. I'm not talking about beginners code, but about professional clean code. If you're doing as a beginner you can still use the $this keyword to make it clearer code for you to understand. But if you want to do huge applications you should have understand the difference between static and non-static context. And if it would be defined well in PHP, modern IDEs should be able to help you to do no mistakes. This is true of any object variable. These resolve the scope of the property/method to the variable $foo: $a = $foo-a; $foo-some_function(...); These resolve the scope of the property/method to the variable $this: $a = $this-a; $this-some_function(...); Okay I agree with this point. If you want to resolve the scope of a method to the current object without using the variable $this, you can also use the static keyword; these are equivalent: $this-some_function(...); static::some_function(...); // http://3v4l.org/E0XYs I don't care whether I use $this- or static:: as keyword. In this case I would even prefer $this- because static in instance context is in my opinion really confusing. There is nothing unvariable-like about $this, so if variables begin with $, $this should begin with $. Regards, Regards -- DerOetzi -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Request Feedback for Instance Variable Sugar RFC
Am 11.03.2015 um 14:03 schrieb Rowan Collins: Johannes Ott wrote on 10/03/2015 20:46: okay indeed the dynamic properties are a problem I didn't think about on my suggestion. Without the wish to hijack this thread for another typesafety discussion, I must say again that PHP needs a less dynamic and more declaratively properties concept in my opinion. Yes, I think a standard way to say that a particular object has strictly declared all its properties, and should not allow would be useful. (Even with that, though, I'd be against guessing that $foo meant $this-foo; it just makes code harder to read.) I disagree, programming Java beside PHP since about 15 years now, personally I think always having this-keyword, where it is not necassary in a strict OOP-world, makes the code more unreadable for the simple fact it is more to read. So I would suggest for now to keep the $this variable, but to make it more similar to other OOP-languages I would suggest to remove the $-character in front. In my opinion it would fit better to other object keywords like parent and self as well. Other OOP languages only don't have a sigil such as $ in front of this if they don't have one in front of *any* variable. Why should $this, which acts like a normal variable in pretty much every way, drop the $ when every other variable in the language has one? Note that the syntax of parent and self is different, and is consistent with static member/method access, or more strictly scope resolution. You can't pass parent or self around as variables, only use them to resolve scopes, so they don't have a $. I only agree a bit, because the keyword this, is what to call a hybridization, more often used to define the scope of the property or method you want to use, then used really as a pure variable. For example: this-a; or this-some_function(...); just defining the scope as in the current instance is much more used then. some_function($this); That's what sigils are for - making similar things look similar and distinct things look distinct. Regards, -- DerOetzi -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] static constructor
What about inheritance? I think dynamic class-constructor would make much more sense. A function which can analyse real class and do initialisation. class A { protected static function __class_construct() { echo get_called_class().” class is defined\n; } } class B extends A { } output A class is defined B class is defined I think class-constructor and static-constructor are two different things. I even think that a inherited class-constructor is a dangerous thing because you have huge depencies between all subclasses. For a quick and dirty example: abstract class A { protected static $value; protected static function __class_construct() { switch (get_called_class()): case 'B': self::$value = 1; break; case 'C': self::$value = 2; break; default: self::$value = 3; } } class B extends A { public static function isOne() { return self::$value == 1; } } class C extends A { public static function isTwo() { return self::$value == 2; } } That not wellformed code for three reasons: 1. Class A must know about all of it's subclasses, so you can not easily reuse this class A in other projects because you have to refactor the complete __class_constructor. 2. Huge dependcies between all subclasses. If you want to implement a class D although extending class A you have to look in each other class for sideeffects of the the changes you have todo in the __class_construct for this class D 3. As you can see in the quick example you have a depency of class loading order as well the result of B::isOne() and C::isTwo() depends in which order you have loaded your classfiles. Even worst for example You are using only class B for the beginn B::isOne() giving you true, later you load class C for another reason and suddenly B::isOne() gives you false. A static constructor however encapsulate the initialization to each class and should only initialize private members which can be accessed by protected getters by the subclass. For the example: abstract class A { private static $one; private static function __static() { self::$one = 1; } protected static function getOne() { return self::$one; } } class B extends A { public static function isOne() { return self::getOne() == 1; //Now always true } } class C extends A { public static function isTwo() { return self::getOne() == 2; //Now always false } } Regards, -- DerOetzi -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] static constructor
Am 12.03.2015 um 05:17 schrieb Levi Morrison: On Wed, Mar 11, 2015 at 6:10 PM, Rowan Collins rowan.coll...@gmail.com wrote: On 11/03/2015 23:21, Johannes Ott wrote: So now I want to do my first own proposal for a new function in PHP and I hope doing it right with starting a discussion here first. The purpose of this suggestion is to introduce a static constructor, which is called before the first call to class either static or non-static to initialize some static properties which are needed by the class. Can you give an example use case for when this would be useful? I'm struggling to think of one for which there isn't already an established coding pattern... Notably, user-land enums. You don't want public constructors because you don't want it instantiated except for each enum property. You also need it to run on class creation, not afterwards. I think we'd be better off adding language-level enums than static constructors though. Yes indeed user-land enums are one of the use cases I use this feature at the moment. But there some other use cases as well: 1. Nearly all of my classes have a static LogAdapter $LOG which has to be intialized with Classname once. class A { private static $LOG; public static function __static() { self::$LOG = LogAdapter::getLogger(self::class); } } A::__static(); The LogAdapter by it selfs although have a __static() method to prepare the Log4PHP-Framework I'm using. 2. Some Config classes which are intelligent wrapper-classes to some ini-files and database have to read in some things first. class Config { private static $ini; public static function __static() { self::$ini = parse_ini_file(...); // or // Read from Database } } Config::__static(); 3. For a multilanguage system I determine the user language by useragent and fallback to default-language if user language ist not supported. class Text { private static $defaultLang; private static $userLang; public static function __static() { self::$defaultLang = //read from Database self::setUserLanguageOrFallback(); } private static function setUserLanguageOrFallback() { ... } } Text::__static(); 4. Already prepare some PDO-statements which needed all over the class class Example { private static $stmts = []; public static function __static() { self::$stmts['select1'] = new DBSelect('SELECT * FROM table WHERE `col1`=:clause'); } } Example::__static(); That are the examples I can found on a quick search over my code. Regards, -- DerOetzi -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] static constructor
Most of these examples are just crying out to be real objects, not static classes. You might not want to be creating them every time you use them, but that's what patterns like Singletons and Dependency Injection are for. I really disagree to this. Singletons are a typical FactoryPattern, none of the examples except the LogAdapter itself are doing implementation of a factory. They are just initialize some computed static variables once in the live time of the class mostly for internal usage of the class. That is nearly like initializing a class constant, but in my opinion a constant should not have a complex algorithm (For example conditions or read from filesystem). That should be encapsulated inside a proper method body. In use case 1 Dependency Injection maybe another solution but does not exactly do what I want to do. 1. Nearly all of my classes have a static LogAdapter $LOG which has to be intialized with Classname once. class A { private static $LOG; public static function __static() { self::$LOG = LogAdapter::getLogger(self::class); } } A::__static(); The LogAdapter by it selfs although have a __static() method to prepare the Log4PHP-Framework I'm using. This particular example could be achieved with a static getLogger() method, which does the initialisation check the first time the logger is needed, rather than the first time class A is needed. yes that would be another valid pattern. And would be prefered for me if I use the Logger in 1 or 2 out of 10 class methods, which are not used very often. But mostly I'm using it in 9 or 10 of 10 methods, which are invoked several times through lifetime. So doing a null check each time is a overhead of calculation which can be avoided with this static constructor pattern. To my mind, the creation of a class in memory should not have side-effects - you should be able to assume that all your classes exist at the same time, before any of your code runs. I agree the real creation(/parsing) of the class should have no side-effects. But the static constructor is not executed at the creation-time of the class but directly before first access on the class. That are two totally different moments in the lifecycle of the class and does not block the possibility to first read all classes without any side-effects. The only justification for not acting that way would be Python-style metaclasses, where the creation of a class definition was the responsibility of some other object, and that's a power to be wielded very carefully. The static constructor or sometimes although called class constructor is a well known OOP-pattern implemented by different languages like C# or Java. Regards, -- DerOetzi -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] static constructor
Am 12.03.2015 um 12:40 schrieb Niklas Keller: How would it behave for the second call? If the first initialize fails due to some exception, should that static constructor be executed again? I think there a two different solutions and I do not know which one I prefer at the moment: 1. No second call can raise an fatal. 2. Yes should be executed again As an internal implementation, we can do a flag which is at creation time of class false and set after sucessful run of the static constructor to true. Do avoid deadlocks in loops like in the example maybe we can implement a combination of both solutions. We can implement the flag not as a boolean but as an integer counter. Raising a FATAL after X retries. Regards, -- DerOetzi -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] static constructor
Am 12.03.2015 um 16:57 schrieb Rowan Collins: Johannes Ott wrote on 12/03/2015 14:51: That is nearly like initializing a class constant, but in my opinion a constant should not have a complex algorithm (For example conditions or read from filesystem). That should be encapsulated inside a proper method body. I agree, but as such, I think that method should be called somewhere by the code, even if only by a DI container, not happen automagically and slurp in data from global state. It is called somewhere in the code namely inside the static constructor :D Consider your prepare some SQL queries example - it has a dependency on a database connection, so that now has to be global state; if that in turn is lazily initialised, it needs to get the connection string from yet more global state, and so on. By using the class constructor, you are forced to hard-code those dependencies - there's no parameters to pass them in, and you can't pre-initialise them from outside the class, because nothing on the class can run before the class constructor. Okay that is a point each developer should be aware and decide by his self. So doing a null check each time is a overhead of calculation which can be avoided with this static constructor pattern. Presumably the engine would need to perform some implicit equivalent of if ( ! self::$initialised ) on each call to decide if the static constructor needs to be called or not, so the overhead is not completely eliminated. Yes you are right but I think it can be done more efficiently inside the interpreter using some struct flags then have to parse each time inside a coded part in the application. Incidentally, note that a recent RFC to add the ability to declare a class as static failed by 12 votes to 5 - https://wiki.php.net/rfc/abstract_final_class - and much of the discussion was around static implementations being generally inferior to instances, so I'm not alone in challenging designs that rely on them. I will check the rfc later but static class sounds strange. Regards, Regards, -- DerOetzi -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] static constructor
Am 12.03.2015 um 18:55 schrieb Rowan Collins: Johannes Ott wrote on 12/03/2015 17:05: Am 12.03.2015 um 16:57 schrieb Rowan Collins: Johannes Ott wrote on 12/03/2015 14:51: That is nearly like initializing a class constant, but in my opinion a constant should not have a complex algorithm (For example conditions or read from filesystem). That should be encapsulated inside a proper method body. I agree, but as such, I think that method should be called somewhere by the code, even if only by a DI container, not happen automagically and slurp in data from global state. It is called somewhere in the code namely inside the static constructor :D What I meant is that it is not executed by any piece of code the user writes, but directly by the engine based on a magic hook. Yes but thats why it is called magic method, isn't it ;) No serious if it is clearly defined what the magic method __static() does and when it is invoked, it should be okay. All of the magic methods are doing like this. Incidentally, note that a recent RFC to add the ability to declare a class as static failed by 12 votes to 5 - https://wiki.php.net/rfc/abstract_final_class - and much of the discussion was around static implementations being generally inferior to instances, so I'm not alone in challenging designs that rely on them. I will check the rfc later but static class sounds strange. I had time to read the linked rfc now. If I understand it right that rfc Means a Util-class-pattern for util-classes which should not be extendable. I don't see the sense of that now, why I util class with only static methods which typically is defined as abstract should not be extendable by other, I cannot remember to have this use cased in my 15 years of OOP-programming but okay maybe there are such use cases. But my proposal is another one see my next comment on your comment below. Basically, all your examples imply classes that consist only of static members - they're not using static helpers to create instances, they're using them *instead of* instances. This was what was mean by static class in that proposal. Personally, I was in favour of that, since I think such classes do exist, and a syntax for declaring them would be useful, but the most common argument against was that we should be finding ways for people to not need such classes, rather than supporting them better. This proposal sounds like it's adding facilities to classes that belong on objects, or ... somewhere else. Okay thats a point I have to clearify I see, maybe my examples where to much shorten by me. In my examples I'm showing only the initialize parts of the classes, the initialized properties are used all over the class in static as well in non-static context. For use case 1 the LogAdapter for example is a singleton instance per class, that's why in my understanding of dependcy Injection it is not working with it (correct me please if I'm wrong). And this singleton is used to log in all methods of the class/object. Surely I would be able to get the specializied Singleton instance with doing some code like the following two examples: Example 1 (As I already would be prefered solution for me if I use the Logger only in a few of the methods and not in the majority of it): class A { private static $LOG; private static function initLogger() { if (self::$LOG = null) { self::$LOG = LogAdapter::getLogger(self::class); } } public static function a() { self::initLogger(); self::$LOG-debug(); self::$LOG-error(); } public function b() { self::initLogger(); ... self::$LOG-error(); } ... } or Example 2: (which is in my opinion really hard to read and to much to write) class A { public static function a() { LogAdapter::getLogger(self::class)-debug(); LogAdapter::getLogger(self::class)-error(); } public function b() { ... LogAdapter::getLogger(self::class)-error(); } ... } With my solution of a static constructor it would look like this. class A { private static $LOG; private static function __static() { self::$LOG = LogAdapter::getLogger(self::class); } public static function a() { self::$LOG-debug(); self::$LOG-error(); } public function b() { ... self::$LOG-error(); } ... } On huge classes with 10 or more methods all using the LOG reference this is in my opinion the cleanest and shortest solution. I hope I could make the example more clear?! If you need more examples please let me know. Regards -- DerOetzi -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] static constructor
Am 12.03.2015 um 20:34 schrieb Rowan Collins: Patrick Schaaf wrote on 12/03/2015 18:40: Am 12.03.2015 18:56 schrieb Rowan Collins rowan.coll...@gmail.com mailto:rowan.coll...@gmail.com: Johannes Ott wrote on 12/03/2015 17:05: So doing a null check each time is a overhead of calculation which can be avoided with this static constructor pattern. Presumably the engine would need to perform some implicit equivalent of if ( ! self::$initialised ) on each call to decide if the static constructor needs to be called or not, so the overhead is not completely eliminated. Yes you are right but I think it can be done more efficiently inside the interpreter using some struct flags then have to parse each time inside a coded part in the application. Yes, point taken. I don't think such a flag is neccessary at all. Any class. at the moment, comes from one or another file that is included / required. And all of the code in these files outside the class definition, is then immediately executed. The only thing neccessary would be to check, just before that execution begins, which of the new classes have such an initializer method, and then call that, before the execution of the file itself begins. This was my initial interpretation, but Johannes has explained that that is not the intention of this proposal. Instead, it is intended to be called on first *use* of the class; a subtle difference, but given this code: Correct! On that point I agree with Rowan, for the fact that there a lot of of libraries and application in user-land which don't use autoload function to include the classes when required, but include all classes at the startup, but on different paths through the application only use a few of them. Or in future the interpreter or a maybe application server will have some optimization which loads the classes it may need already in memory, but never use it then. The static constructor pattern should avoid overhead in all of this current and possible future cases. Instead the static constructor should behave like the following user-code: class A { private static $bInitialized = false; ... private static function init() { if (self::$bInitialized) { return; } ... self::$bInitialized = true; } public static function a() { self::init(); ... } public function b() { self::init(); ... } ... } So we need the $bInitialized flag in the struct. Another point already mentioned for the example where the static constructor uses database connection or something there can be a lot of unnecassary db-connections opened on creation time. Regards, -- DerOetzi -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] static constructor
Am 12.03.2015 um 21:33 schrieb Rowan Collins: Johannes Ott wrote on 12/03/2015 19:45: All of the magic methods are doing like this. I thought you might say that, but the only thing remotely similar I can think of is a destructor, which gets called when an object goes out of scope; the others are all the implementation of, or instead of, some specific piece of code: __construct() runs every time for new Foo __get() and __set() runs every time for property access with - on an undefined property __call() and __callStatic() runs every time for method access on an undefined property The difference with this is that you never know which part of your code will actually trigger it, because it only runs some of the time. I cannot see any difference because the trigger is defined really clear for each of the functions For Example Class Foo implements all of those functions the triggers would be __construct - triggered each time I write new Foo() __destruct - triggered each time a instance loses his last reference and is removed by garbage collection. __get() and __set() - triggered each time I try to access a property of my foo instance which is not accessible (not defined or private) from outside Foo writing $foo-notfromoutside __call() - triggered each time I try to call a non-static method on a instance of Foo which is not accessible from outside writing $foo-notfromoutside() __callStatic() - triggered each time I try to access static method of the class which is not accessible from outside writing Foo::notfromoutside() And finally the proposed new one __static() - triggered on the first time I write either new Foo() or Foo::eachStaticPublicOrProtectedMethodOrProperty() I really don't see what __static() has more magic or unclear trigger then each of the other so called magic methods?! Do keep away any doubt, in my opinion none of the so called magic methods have any kind of magic. They are just language patterns you should understand how they work before you start to use them in your code! So private static function __static() {...} is just another pattern you have to understand before you use. If you don't understand how it works you should not use. That is the same for all language patterns and elements, for example: loops, conditions, scalar-operators, etc. And as I already told a static class constructor is a kind of well-known standard function in mostly all modern OOP-languages. So professional OOP-developer should be or become very fast familiar with this pattern. Okay thats a point I have to clearify I see, maybe my examples where to much shorten by me. In my examples I'm showing only the initialize parts of the classes, the initialized properties are used all over the class in static as well in non-static context. OK, so these are classes which share certain resources between all instances, represented by these static properties. In that case, would it be reasonable to say that the initialization of these properties needs to happen the first time an instance is created? If so, the if(self::$initialized) check needs to run only as often as __construct(), not every time any method is called. If you look closer at my example you will see, that the property is not just shared between instances (then the normal constructor Could be indeed be the place to initialize), but it is shared although with different static methods inside the class. If the static methods are public, and used for something other than managing instances (Factory / Singleton / etc), then are they really the responsibility of the same class? i.e. do you have a Utility class hiding in there pretending to be part of the instance/factory class? See my example 2 for a Config Wrapper class: abstract class Config { private static $arIni; private static function __static() { self::$arIni = parse_ini_file('config.ini'); //For example check whether all required fields are in the file or throw Exception if not. } public static function getHostname() { return self::$arIni['hostname']; } public static function getDBConnectionString() { return ' self::$arIni['dbdriver'] . '://' . self::$arIni['dbuser'] . '@' .self::$arIni['dbhost'] ...; } ... } The Config class is in response for all config Parameters inside config.ini and needs to read in this file before it can to it's work correctly. No hiding of Factory/Singleton/instance in this. And i although see no DI or Singleton pattern to use here to get the same functionality, if you want to use like Config::getHostname() and not like Config::getInstance()-getHostname() which is really unnecessary abstraction level for nothing in my opinion! For use case 1 the LogAdapter for example is a singleton instance per class, that's why in my understanding of dependcy Injection it is not working with it (correct me please if I'm wrong). And this singleton is used to log in all
Re: [PHP-DEV] static constructor
Am 12.03.2015 um 12:16 schrieb Crypto Compress: Hello Johannes, class Foo { private static function __static() { throw new Exception(boom); } } while(true) { try { $foo = new Foo; } catch (Exception ex) {} } Would this code be valid? Have to think about this issue, but on the first look I would say yes! Because the meaning of the static constructor is to do some necassary initialize for the class it should be able to throw an Exception if it cannot do it's work correctly. For example if it needs to read some configuration from a Database and is not able to connect. For the caller I although would say, that the error inside the static constructor should be catchable, for the simple fact that every Error should be catchable for user-errorhandling. What is your point of view for this? I'm open for discussion about this. Regards -- DerOetzi -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Request Feedback for Instance Variable Sugar RFC
Am 11.03.2015 um 18:12 schrieb Rowan Collins: Johannes Ott wrote on 11/03/2015 16:46: Am 11.03.2015 um 17:21 schrieb Rowan Collins: My reasoning is that code that is ambiguous is hard to read. If $foo can mean either a local variable called $foo or a property of the current object called $foo, then you have to know which it is in order to understand what code is doing. So for clean code rules you should do smaller methods if you can't even see clearly whether you declared $foo locally or not. True, but again, PHP doesn't give you a way of declaring that a variable *is* local, so it would be impossible in isolation to tell if $rate in this example is a property or just a temporary variable: public function setRatePercentage($rate_percent) { $rate = $rate / 100; $processed_amount = $amount * $rate; } As I said before I totaly agree for current state of PHP that with dynamic properties without declaration inside any scope we need a $this operator as mandatory. But in future if maybe we will have declaration, typesafety etc. I would vote then for a more java like behavior. This is not about a strict OOP-world, incidentally, it's about scoping rules. Java imports object properties into the scope of each method, PHP does not. Even if properties had to be declared (which is probably a good idea), local variables still wouldn't be - in Java, the fact that it's not declared locally means it *must* be coming from somewhere else. No if it is not declared locally it doesn't mean it's coming from somewhere else, but it means it is coming from one of the next higher scopes which is normally the Object. By somewhere else, I meant somewhere other than the local scope, so we're both saying the same thing here. I also know that when I was first learning Java at school, it confused me immensely which variables I was allowed to access in static contexts. In PHP, that's simple - if you can't access $this, you can't access any of it's properties. I'm not talking about beginners code, but about professional clean code. If you're doing as a beginner you can still use the $this keyword to make it clearer code for you to understand. A lot of beginners start by reading other people's code, or get jobs working alongside experts. Having completely different styles of programming for experts and beginners harms collaboration. Yes I agree, but the beginners have to learn to read and understand and later on to write the expert code, that is no point for me to polute code with unnecessary snippets, because it will make it much harder to maintain then for everyone. And the best collaboration is to ask the experts to teach yourself. It is often observed that code is read much more often than it is written. This argument really is a point for me. Because if you have lot of optional-keywords you have more to read and in worst case even to scroll horizontal. But I think we should come back to the topic of this thread, I would say that we should keep $this like it is for the moment, because of some other lecks in scope and variable concept of PHP. And I don't see the need of a shortcut-symbol for $this- because that really makes the code much harder to read then the keyword this do. Regards -- DerOetzi -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Basic Scalar Types
Am 11.03.2015 um 22:28 schrieb Bob Weinand: Hi all, after all, some people are not happy with the current proposals about scalar types. So, they both still possibly may fail. Thus, I'd like to come up with a fallback proposal in case both proposals fail: https://wiki.php.net/rfc/basic_scalar_types It shouldn't prevent any future improvements and still give use all the advantages of scalar types. Thanks, Bob From me although a +1 vote. -- DerOetzi -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Re: Introduce DerOetzi
Am 11.03.2015 um 15:05 schrieb Niklas Keller: You have to input internals@lists.php.net, that changed some time ago. I've just updated https://wiki.php.net/rfc/howto See https://github.com/php/web-wiki/commit/583d2c1b39a8b88960ab94e56ba4a4608ddb2353 Regards, Niklas Thanks that helped. But still the question why the formular has no error messages what went wrong? Regards -- DerOetzi -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] static constructor
Am 12.03.2015 um 00:30 schrieb Marco Pivetta: Hey Johannes, Why can't this be done at autoloading time? In my opinion this should not be done on autoloading time, but as a own method inside the class for two reasons. 1. Not every class is loaded with autoload-functions, but although directly with include_once or required_once functions 2. The initialization of needed things inside the class should be in the domain of the class itself and not of someone outside. Thats why I proposed to make it a private magic method not a public one. To do by autoload or by calling it inside the included file after class-definition like class B { ... } B::__static(); would require to make it public and means to give the responsibility to do the necessary initialization to someone else. Marco Pivetta http://twitter.com/Ocramius http://ocramius.github.com/ Regards, -- DerOetzi -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
[PHP-DEV] static constructor
So now I want to do my first own proposal for a new function in PHP and I hope doing it right with starting a discussion here first. The purpose of this suggestion is to introduce a static constructor, which is called before the first call to class either static or non-static to initialize some static properties which are needed by the class. I think about two different possible syntax to realize that purpose: Version 1 (similar to Java): class A { private static $var; static { //Do some code here to initialize self::$var; } } Version 2 (a new magic method): class B { private static $var; private static function __static() { //Do some code here to initialize self::$var; } } My prefered code would be version 2 at the moment. Looking forward to your feedback, -- DerOetzi -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
[PHP-DEV] Re: Introduce DerOetzi
Am 11.03.2015 um 14:25 schrieb Christoph Becker: Johannes Ott wrote: BTW: I'm trying to register a wiki account. But somehow it does not work. When posting the formular the page is reloading, but nothing else happens. No success or no error message is shown. Maybe I'm doing something wrong?! Maybe you have not filled out the fourth field (Which email address do you have to mail now?) correctly. I think I have filled correctly all fields, but even if not why is the formular not giving any visible information what went wrong? I will retry later. -- DerOetzi -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
[PHP-DEV] Introduce DerOetzi
Hi, sorry I did the wrong order, starting to discuss already without introducing me first: My name is Johannes Ott. I am 31 years old. I'm developing with PHP since 2004, I have written my thesis about Testdriven development of a PHP- Framework with namespaces and 'typesafety' as implemented in PHP 5.3. I have developed some kind of autoboxing of scalar types and a new Master- Object like used in Java. Currently I'm working as a senior J(2)EE developer and as a Software Architect for a huge Oracle ADF project since 2 years now. But I'm still programming PHP for my hobby. I'm really interested in PHP7 new hashtable things and compiler issues. If you want more visit my Xing profile: https://www.xing.com/profile/ Johannes_Ott5 Regards DerOetzi -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Request Feedback for Instance Variable Sugar RFC
Hi, okay indeed the dynamic properties are a problem I didn't think about on my suggestion. Without the wish to hijack this thread for another typesafety discussion, I must say again that PHP needs a less dynamic and more declaratively properties concept in my opinion. So I would suggest for now to keep the $this variable, but to make it more similar to other OOP-languages I would suggest to remove the $-character in front. In my opinion it would fit better to other object keywords like parent and self as well. so i would prefer this-... instead of $this-... Regards -- DerOetzi -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] Request Feedback for Instance Variable Sugar RFC
Hey as developing both Java and PHP, I would suggest a solution similar to Java. As long as there is no conflict to a local variable the keyword $this should be the default. Regards DerOetzi -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php