Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:69633 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 84784 invoked from network); 17 Oct 2013 15:31:09 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 17 Oct 2013 15:31:09 -0000 Authentication-Results: pb1.pair.com header.from=rowan.collins@gmail.com; sender-id=pass Authentication-Results: pb1.pair.com smtp.mail=rowan.collins@gmail.com; spf=pass; sender-id=pass Received-SPF: pass (pb1.pair.com: domain gmail.com designates 74.125.83.41 as permitted sender) X-PHP-List-Original-Sender: rowan.collins@gmail.com X-Host-Fingerprint: 74.125.83.41 mail-ee0-f41.google.com Received: from [74.125.83.41] ([74.125.83.41:36527] helo=mail-ee0-f41.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id B6/5F-12663-CB200625 for ; Thu, 17 Oct 2013 11:31:09 -0400 Received: by mail-ee0-f41.google.com with SMTP id b15so925997eek.14 for ; Thu, 17 Oct 2013 08:31:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=message-id:date:from:user-agent:mime-version:to:subject:references :in-reply-to:content-type:content-transfer-encoding; bh=/8gT74qNpdYqrGISX5YICeC2vE/gWCCiYlh8Y3YCizA=; b=yMVlYFc0hYWbNzlK7JRTr7D04puysiXWo0tW8tI+O3Gwz6PXV5Q0AVp07iCcrEmtsK T1zP+Mzsy+8MK+OKe2hCjTWSpRWh3RXpIPAZzQYAnGpfi5QJlAin9y2qFK7NB+HK3lrZ YgwDr2DDF+KfoDOSXB4lCVxJWkYgWV0EDKmiDL4wlfZW10hkmIQQc9vqZSW1QGkr18/b tZfZHqZU4QloPrbat8wDUrqZpT4KAQBLu8lyes47BuJde2szALVYjLJxI4m/rvDP6xF1 ThKiqf/Fj+VvJ4dT76cAsvLjmBKWrQulWZvbKSsQGBjh/MP/saRPe3YlF1A3+Gcbz6xi bHuA== X-Received: by 10.204.105.198 with SMTP id u6mr7514846bko.19.1382023866349; Thu, 17 Oct 2013 08:31:06 -0700 (PDT) Received: from [192.168.0.2] (cpc19-brig17-2-0-cust25.3-3.cable.virginmedia.com. [81.101.201.26]) by mx.google.com with ESMTPSA id l5sm50783921bko.7.1969.12.31.16.00.00 (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 17 Oct 2013 08:31:05 -0700 (PDT) Message-ID: <526002B4.9010808@gmail.com> Date: Thu, 17 Oct 2013 16:31:00 +0100 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:24.0) Gecko/20100101 Thunderbird/24.0.1 MIME-Version: 1.0 To: PHP Internals References: <525C631E.1050008@gmail.com> <1381853515.3980.195.camel@guybrush> In-Reply-To: <1381853515.3980.195.camel@guybrush> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit Subject: Re: [PHP-DEV] Proposal to deprecate create_function() From: rowan.collins@gmail.com (Rowan Collins) On 15/10/2013 17:11, Johannes Schlüter wrote: > In general: Getting rid of it is good. But mind that closures are no > full replacement as with create_function() the code can be created on > the fly. Yes, I agree that there is no trvial solution which is 100% feature (and bug) compatible with create_function(). However, I think the more important question is whether there are any particular *use cases* which can't be easily migrated to a different mechanism. My gut feel is that at least 95% of uses of create_function are to create dynamic callbacks for usort, preg_replace_callback, array_filter, etc. For these uses, the implementation as an eval() is a liability, and reimplementing with real closures is trivial (assuming no need to run on <=5.2). The remaining uses may be taking deliberate advantage of the fact that it's an eval() wrapper, but most of those could in turn be trivially replaced with a user-defined function that uses eval() to return a new closure. Only code that is somehow relying on the fact that the return is a string of the function name would need to worry about picking a unique name, and an even smaller proportion of those would care that the prefix begins with a null byte rather than some other arbitrary string. > Emulating it with eval() is also complicated as it has this > nice trick of creating function names which start with \0 and therefore > don't appear in function lists. The only function list I know of is get_defined_functions(), which does indeed exclude properties with a leading null byte, via an internal function named copy_function_name. It's not clear from the logs whether that was a deliberate decision or a side-effect of some other use of null bytes. Elsewhere, function_exists() returns true for these "anonymous" functions, and ReflectionFunction is able to see them, although it confusingly thinks their name is still __lambda_func. Since closures are also not visible in get_defined_functions(), for this to matter, somebody would have needed to write code that relied simultaneously on their function being referable to by name *and* it not appearing in that particular list. It's certainly possible that somebody would be forced to do some more serious rewrites if that exact combination weren't possible, but it seems extremely unlikely to me. Regards, -- Rowan Collins [IMSoP]