Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:55373 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 62685 invoked from network); 11 Sep 2011 22:26:20 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 11 Sep 2011 22:26:20 -0000 Authentication-Results: pb1.pair.com smtp.mail=glopes@nebm.ist.utl.pt; spf=permerror; sender-id=unknown Authentication-Results: pb1.pair.com header.from=glopes@nebm.ist.utl.pt; sender-id=unknown Received-SPF: error (pb1.pair.com: domain nebm.ist.utl.pt from 193.136.128.22 cause and error) X-PHP-List-Original-Sender: glopes@nebm.ist.utl.pt X-Host-Fingerprint: 193.136.128.22 smtp2.ist.utl.pt Linux 2.6 Received: from [193.136.128.22] ([193.136.128.22:59673] helo=smtp2.ist.utl.pt) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id AD/D1-49174-8853D6E4 for ; Sun, 11 Sep 2011 18:26:17 -0400 Received: from localhost (localhost.localdomain [127.0.0.1]) by smtp2.ist.utl.pt (Postfix) with ESMTP id F254970003D2 for ; Sun, 11 Sep 2011 23:26:13 +0100 (WEST) X-Virus-Scanned: by amavisd-new-2.6.4 (20090625) (Debian) at ist.utl.pt Received: from smtp2.ist.utl.pt ([127.0.0.1]) by localhost (smtp2.ist.utl.pt [127.0.0.1]) (amavisd-new, port 10025) with LMTP id S0neIKI5Ur5s for ; Sun, 11 Sep 2011 23:26:13 +0100 (WEST) Received: from mail2.ist.utl.pt (mail.ist.utl.pt [IPv6:2001:690:2100:1::8]) by smtp2.ist.utl.pt (Postfix) with ESMTP id 9F9AC70003CE for ; Sun, 11 Sep 2011 23:26:13 +0100 (WEST) Received: from cataphract.cata.lo.geleia.net (cataphract.cata.lo.geleia.net [IPv6:2001:470:94a2:1:b488:8610:90e4:7835]) (Authenticated sender: ist155741) by mail2.ist.utl.pt (Postfix) with ESMTPSA id B8BC42003A3A for ; Sun, 11 Sep 2011 23:26:12 +0100 (WEST) Content-Type: text/plain; charset=utf-8; format=flowed; delsp=yes To: internals@lists.php.net References: <4E6D0B5C.8030907@php.net> Date: Sun, 11 Sep 2011 23:26:07 +0100 MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Organization: =?utf-8?Q?N=C3=BAcleo_de_Eng=2E_Biom=C3=A9di?= =?utf-8?Q?ca_do_IST?= Message-ID: In-Reply-To: <4E6D0B5C.8030907@php.net> User-Agent: Opera Mail/11.51 (Win32) Subject: Re: [PHP-DEV] [RFC] Factory for Stream Wrappers From: glopes@nebm.ist.utl.pt ("Gustavo Lopes") On Sun, 11 Sep 2011 20:26:20 +0100, Sebastian Bergmann wrote: > [...] > -- > [1] https://wiki.php.net/rfc/streamwrapper-factory > [2] http://schlueters.de/~johannes/php/stream_factory.diff > A patch against trunk (or 5.4) would have been nicer. Other than that: * This patch has a huge BC: PHP_FUNCTION(stream_wrapper_register) { ... - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|l", &protocol, &protocol_len, &classname, &classname_len, &flags) == FAILURE) { + + uwrap = (struct php_user_stream_wrapper *)ecalloc(1, sizeof(*uwrap)); + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sf|l", &protocol, &protocol_len, &uwrap->fci, &uwrap->fcc, &flags) == FAILURE) { + efree(uwrap); It should be changed so that the current form of stream_wrapper_register is still accepted. I assume this is a mistake because user_wrapper_get_object still tries to instantiate an object directly if there's no callback. * Calling the object handler get_class_name is nicer than using Z_OBJCE_P(us->object)->name) because it works with more objects. * You claim this has two advantages -- 1. Allows to inject state into stream wrappers from other parts of the application without having to access global state or encode information into the stream uri. 2. Increases testability of code using stream wrappers. Could you add some examples substantiating these claims? I have some doubts. If your factory is a function, #1 doesn't seem to apply. The only way I see you can retrieve state to inject is by exactly the same means available on the wrapper object constructor or stream_open (with the aggravating factor that in stream_open you have access to the context and to the URI, but in the factory you have access to none). If, however, the factory is an object method, I see that you could change state in the object and the factory method would have access to this new state (and could inject in the wrapper object). Claim #2 is more dubious. Adding a level of indirection in object creation is indeed useful for testing because you can inject to objects that need to instantiate other objects a different factory that will return mock objects. However, I don't see how this applies here. The stream wrapper already doesn't have a fixed dependency; it functions like a basic factory, instantiating an object of a class you give. You can already swap the implementation of a stream wrapper by varying the class name upon registration. So I don't see how you gain anything with this extra complexity. -- Gustavo Lopes