Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:95663 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 10635 invoked from network); 5 Sep 2016 17:38:11 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 5 Sep 2016 17:38:11 -0000 X-Host-Fingerprint: 90.212.141.121 unknown Received: from [90.212.141.121] ([90.212.141.121:21550] helo=localhost.localdomain) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id A2/D5-45301-28DADC75 for ; Mon, 05 Sep 2016 13:38:11 -0400 Message-ID: To: internals@lists.php.net References: Date: Mon, 5 Sep 2016 18:38:06 +0100 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:43.0) Gecko/20100101 Firefox/43.0 SeaMonkey/2.40 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit X-Posted-By: 90.212.141.121 Subject: Re: [PHP-DEV] Missing reflection info about strict types? From: ajf@ajf.me (Andrea Faulds) Hi, Nicolas Grekas wrote: > Thanks for trying Julien > > I guess what you miss for what you want to do, is to detect if strict >> types are activated into the current scope, at runtime. >> > > From the inside, the author of the code knows if they added the declare or > not. > I'd need to know from the outside, before concatenating it, if some file > has strict types. > This could be exposed on the reflection, since a function/method/class > could have a flag that tells if it has been compiled with strict types > enabled or not. > The current alternative is to parse the source to check if it starts with > the declare directive (but not trivial because of non semantic tokens). > > Here is my current regex to do so: >> $c = '(?:\s*+(?:(?:#|//)[^\n]*+\n|/\*(?:(?> $strictTypesRegex = str_replace('.', $c, "'^<\?php\s.declare.\(.strict_ > types.=.1.\).;'is"); Reflection deals with classes, functions, and so on, but it doesn't deal with files. Files are, for the most part, a detail that is only represented when code is compiled (e.g. when an include or require statement is run, or when a script is executed by a request or from the command line). After that compilation stage, however, there's no structure for a “file” in memory (beyond maybe in OPcache). The constants, functions, classes and variables it defines are kept track of by the PHP interpreter, but the file itself isn't directly. Because of this, implementing a reflection method to tell you whether a file uses the strict_types directive isn't currently possible. To the best of my knowledge, PHP doesn't maintain a registry of files in memory which tracks whether they use strict typing or not. Instead it marks any code originating from strictly-typed files as using strict mode. I suppose the PHP interpreter could be modified so it kept track of this information. Though, if you're concatenating arbitrary source files, I feel like reflection might be the wrong tool to use. I think reflection is more intended for inspecting your own codebase, rather than analysing arbitrary PHP files. In order to use reflection on some PHP file, you have to include it first, and you can't un-include it later. You also can't prevent any top-level PHP code in that file from executing when you include it. If you don't need to know whether a /file/ specifically uses strict typing, and only need to know which classes do, that might be possible, given PHP does know at runtime which methods use strict typing. Again, though, I'm not sure if reflection is the best tool. Your best hope is probably to try and parse the file using PHP-Parser or the Tokenizer extension. I hope this is helpful. -- Andrea Faulds https://ajf.me/