Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:112972 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 49770 invoked from network); 24 Jan 2021 16:36:22 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 24 Jan 2021 16:36:22 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 13C6F1804D1 for ; Sun, 24 Jan 2021 08:17:22 -0800 (PST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on php-smtp4.php.net X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SPF_HELO_PASS, SPF_PASS autolearn=no autolearn_force=no version=3.4.2 X-Spam-Virus: No X-Envelope-From: Received: from NAM12-BN8-obe.outbound.protection.outlook.com (mail-bn8nam12olkn2044.outbound.protection.outlook.com [40.92.21.44]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Sun, 24 Jan 2021 08:17:21 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=Uq3le+Hp44OywpS/UcN7J1ZrwroawwwgAptVtY//E/zs+CTfqbHO1/y1dnbjIXtRoNF01Rp+wV4KePL8c14RcviNWR2gUrsMztAZQV0O9rq6U9DPfDWC79bk7VGOjZ9ayC4jsrY2yNjoaVMkIb3qsdtRKTfz4eEHfPJ/BNC9Pswui32cr5odfsvssHHtiPFs2YwyNPBmvioLFwtD8j3qLFGRDd3SP6SaAoh/cZjbARTrdEsQ543jaiGpJtwmNXaggcZd0Aek18sB6q1QSqgRxHW0qpMDiB5tsxkRAgsOUqcKBcj2bE+HFf8gQ5MVUwIG0n3OtrRpxna4l8dE96J0Lg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=HuX9oVsFW6KzSdrJ8HfNCw84tqPFu/qaKobd8Kj2cag=; b=CDDSbbKOWxMwlfdg4XQklzxThl50RVfl9r2xq/aYgRfkmhZlzo7Pqdj2u9flpSHuUadN124jkld9Z3mPAPcsGdog20GHuXU7tHLPx3doSiZNdhx+94H2kHYJuyZ8kuRzS8nZTJUOdyKAfdLTQ+Ng3eYaLoa61O6354vizXUFu40n9Cdsj5r0OfjJ6OteI1Ihz136dBsq4wlGmEoV5D0+RO9I63O65QsU+rgvpUT2ffD5x1673Ik/w8FrQikgQLur66fDYsKmxK25lvtawkpSJxV+6AVAvL3uuGcTX33MIdGtOOGTemZau7e3tNmBCRUTd4eNMIZLv75bHqNbIPyt2g== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=none; dmarc=none; dkim=none; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=hotmail.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=HuX9oVsFW6KzSdrJ8HfNCw84tqPFu/qaKobd8Kj2cag=; b=EW0h2ToGRcujZXCNIMJQfY7dkgh6wXlUJVn1f+jP52vairq+pkW4TfXFqCRWJw9uUuKDGIokV/Zr1TzjPFJySnsx5nExOzGbQsP3bi8x8pQ8UIz9fpuZagQYX9qOL/ouJC5iDrSxCpdgRSg2rWxLc5mmUQGVAJgzJRHVqMNLA/mmL9UQCyEJBcRhZrgJiKCx8873l4ZZWql6fS08HYTSFjMOYBaPNqix9XwiQppQgL/f/8OVknfGKPexyOm04KseIEbZ6kBqxDEjVmo8Tg59kk8pJTCvyzTqEBBB82FEKbq5gV0WsmUjKLvPF6aF+jpkaoMONk/0VTJpFKpuHFgmTA== Received: from BN8NAM12FT031.eop-nam12.prod.protection.outlook.com (2a01:111:e400:fc66::50) by BN8NAM12HT204.eop-nam12.prod.protection.outlook.com (2a01:111:e400:fc66::66) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3805.6; Sun, 24 Jan 2021 16:17:20 +0000 Received: from DM6PR07MB6618.namprd07.prod.outlook.com (2a01:111:e400:fc66::4a) by BN8NAM12FT031.mail.protection.outlook.com (2a01:111:e400:fc66::320) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3805.6 via Frontend Transport; Sun, 24 Jan 2021 16:17:19 +0000 Received: from DM6PR07MB6618.namprd07.prod.outlook.com ([fe80::b4c4:dc11:5337:821d]) by DM6PR07MB6618.namprd07.prod.outlook.com ([fe80::b4c4:dc11:5337:821d%4]) with mapi id 15.20.3784.017; Sun, 24 Jan 2021 16:17:19 +0000 To: Rowan Tommins , "internals@lists.php.net" Thread-Topic: [PHP-DEV] [RFC] var_representation() : readable alternative to var_export() Thread-Index: AQHW8R1wWWGP+37l0kiexDpDbUAmVKo1egmAgAAyURKAAR7sgIAAHRck Date: Sun, 24 Jan 2021 16:17:19 +0000 Message-ID: References: <5ae166a8-378e-b3bc-056a-8ccf4f3a1ddd@gmail.com> , In-Reply-To: Accept-Language: en-CA, en-US Content-Language: en-CA X-MS-Has-Attach: X-MS-TNEF-Correlator: x-incomingtopheadermarker: OriginalChecksum:135B042CFFFBE7D399FAB2BDA92C1018152046E6C3627F6CC3B42CB00632A2E6;UpperCasedChecksum:9A8B9DEE55FD2ACC661E5D6BC2FE16CED65D6AC84C8BD141C156CC273E4DD7E5;SizeAsReceived:7329;Count:44 x-ms-exchange-messagesentrepresentingtype: 1 x-tmn: [umzNrvBDiDTpnT8eWMC04I+QIWgD9VcQ3uX24b++DRxbyMujeyvEo9tV5KTUIpLB] x-ms-publictraffictype: Email x-incomingheadercount: 44 x-eopattributedmessage: 0 x-ms-office365-filtering-correlation-id: 2af28db3-b361-44a3-ad9d-08d8c0838630 x-ms-traffictypediagnostic: BN8NAM12HT204: x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: OnHsJyOAV4YUkAcLPG0FtR09PuTTJMJN8eoAUJ6iDqwKZ7JKWpGd5SDtJED2AmFvuCagCgjqouUpNiPnmkq6OF7v6fXYbs6Gcx+g4PXEHsO+v0OR6c6CZO/NguiMAwkst1Z1FNmWQrrS9W7MQEBPY3B/pYdVIVq6AyzqXUM3Q1OKQMMyrcVdUScoOcHpfSh+HQ1fZMgSOtBjlZLJWt4/vrzqh5e5zcH5OE3NkhmUKmvwvpEd7PNGYRSo7yvK4MB8PbYxp0cCDckmr3lTBjtki99ua1N8lhylAVARk7CcxHc= x-ms-exchange-antispam-messagedata: 40gYx6D6YfbUhePURswtj3NUFhB3qpsE2mmPTY1YrlhSuBOALYFiuzdUF5L+DHNriFb7oSociQo3YR7XqA1HQQ09WlPhidpcvknbzmd6GuvQebYxT9BdMdMSavsNEzop4yAska5kmyePdPdPFUhVbnLX54wuAoVgPEaFTXy/inB4E65HX2tvEfh2EhPqQy52hhUmz6eZacjZ0TS4RgGtbw== x-ms-exchange-transport-forked: True Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-OriginatorOrg: hotmail.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-AuthSource: BN8NAM12FT031.eop-nam12.prod.protection.outlook.com X-MS-Exchange-CrossTenant-RMS-PersistedConsumerOrg: 00000000-0000-0000-0000-000000000000 X-MS-Exchange-CrossTenant-Network-Message-Id: 2af28db3-b361-44a3-ad9d-08d8c0838630 X-MS-Exchange-CrossTenant-originalarrivaltime: 24 Jan 2021 16:17:19.6501 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Internet X-MS-Exchange-CrossTenant-id: 84df9e7f-e9f6-40af-b435-aaaaaaaaaaaa X-MS-Exchange-CrossTenant-rms-persistedconsumerorg: 00000000-0000-0000-0000-000000000000 X-MS-Exchange-Transport-CrossTenantHeadersStamped: BN8NAM12HT204 Subject: Re: [PHP-DEV] [RFC] var_representation() : readable alternative to var_export() From: tysonandre775@hotmail.com (tyson andre) Hi Rowan Tommins,=0A= =0A= > > var_representation=A0 may be useful to a user when any of the following= apply:=0A= > >=0A= > > - You are generating a snippet of code to eval() in a situation where t= he snippet will occasionally or frequently be read by a human=A0 (If the ou= tput never needs to be read by a human, `return unserialize(' . var_export(= serialize($data), true) . ');` can be used)=0A= > =0A= > =0A= > As far as I know I have never had any reason to generate code and then = =0A= > eval() it, and can't think of a situation where I ever would. If I =0A= > wanted a machine-readable output from a variable, I would use =0A= > serialize() or json_encode().=0A= >=0A= > That's not to say that there aren't cases where those requirements do =0A= > happen, but I think it is a very niche use case to dedicate two =0A= > different built-in functions to.=0A= =0A= Even if a developer such as yourself doesn't need to generate code and don'= t expect to directly use it,=0A= **some of the applications and libraries they do use everyday would need to= generate human and machine readable code.**=0A= That output is then shown to users of those libraries/applications,=0A= or saved to files that would need to be looked at by users submitting bug r= eports or trying to understand the issue,=0A= e.g. trying to understand why a unit test mock isn't doing what they'd expe= ct.=0A= =0A= For example, the output of some composer autoload files are generated using= var_export,=0A= and composer uses var_export for generating some exception messages,=0A= and it may be useful to have $e->getMessage() be a single line.=0A= https://github.com/composer/composer/blob/master/src/Composer/Repository/Fi= lesystemRepository.php#L205-L208=0A= (if users were trying to diagnose composer not autoloading the class, havin= g these files be more readable would be useful=0A= many years from now if composer's minimum version became php 8.1)=0A= =0A= And a subset of the uses of var_export in the dependencies of a project I'm= using:=0A= =0A= ```=0A= vendor/sebastian/global-state/src/CodeExporter.php=0A= // in protected function recursiveExport=0A= 67: return \var_export($variable, true);=0A= =0A= 70: return 'unserialize(' . \var_export(\serialize($variable), true)= . ')';=0A= =0A= vendor/phpunit/php-code-coverage/src/Report/PHP.php=0A= 16: * Uses var_export() to write a SebastianBergmann\CodeCoverage\CodeCover= age object to a file.=0A= =0A= 37: \var_export($coverage->getData(true), true),=0A= =0A= vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/ClassCodeGenerator.p= hp=0A= 104: $php .=3D ' =3D '.var_export($argument->getDefault(), t= rue);=0A= =0A= vendor/symfony/console/Descriptor/MarkdownDescriptor.php=0A= 62: .'* Default: `'.str_replace("\n", '', var_export($argument->= getDefault(), true)).'`'=0A= ```=0A= =0A= If you want to distinguish between array, stdClass, and MyClass, json_encod= e isn't adequate.=0A= =0A= > > - You are writing unit tests for applications supporting PHP 8.1+ (or a= var_representation polyfill) that test the exact string representation of = the output (e.g. phpt tests of php-src and PECL extensions)=0A= > =0A= > =0A= > Since test output doesn't need to be executable, I would have thought =0A= > var_dump would be more appropriate than var_export here.=0A= =0A= https://www.php.net/var_dump does not have an option to save to a string - = it outputs to stdout.=0A= if __debugInfo or an error handler echoes anything that would get captured = by output buffering and interfere with that test.=0A= =0A= Additionally, humans need to update the test expectations and to read the t= est output when it fails.=0A= If that output contains control characters or unexpectedly mixes line endin= gs, it is inconvenient to work with files using the raw output of in var_ex= port/var_dump.=0A= =0A= > > As I mentioned before, var_export suffers from many shortcomings such a= s the fact=0A= > > that it can have more lines of output than var_dump for complex datastr= uctures,=0A= > > and doesn't escape control characters.=0A= > =0A= > Checking on php-src master, this does seem to be the case in the =0A= > majority of tests:=0A= > =0A= > - var_export appears 703 times in 136 different *.phpt files (0.8% of fil= es)=0A= > - print_r appears 827 times in 342 different *.phpt files (2.1% of files)= =0A= > - var_dump appears 33503 times in 9599 different *.phpt files (59.7% of = =0A= files)=0A= > =0A= > So if we want to improve anything for that use case, we need to improve = =0A= > or replace var_dump, not var_export.=0A= =0A= **php-src phpt tests are for tests of php itself, which puts strict and aty= pical limitations on the test framework.**=0A= php-src's phpt test framework may represent needs of php-src and some pecl = maintainers, not userland.=0A= In a userland project, I could easily choose to add a whole lot of utility = functions/methods such as=0A= `function dump_repr($value) { echo var_representation($value), "\n"; }` and= use that to replace var_dump.=0A= =0A= I consider adding those helper methods **to php-src itself** impractical be= cause tests of php-src should be self-contained.=0A= If you encounter an issue with the engine, opcache or JIT, it's much, much = harder to diagnose if dozens of userland helper functions=0A= were loaded and invoked before the snippet in question was invoked.=0A= =0A= So I do use var_dump in phpt tests itself, mainly because:=0A= =0A= 1. Currently, control characters such as `\r` are not escaped, so I'm more = confident `string(4) "test"` has no control characters =0A= 2. var_export does not append a newline, it's more convenient to copy the .= out file into the `--OUT--` section=0A= 3. I'm avoiding adding reusable helpers in a self-contained test case =0A= 4. var_export output make the overall test output longer for arrays of arra= ys=0A= =0A= Still, I would prefer using var_representation over var_dump in phpt for ma= ny use cases, especially with VAR_REPRESENTATION_SINGLE_LINE available.=0A= =0A= > > - You need to copy the output into a codebase that's following a modern= coding style guideline such as modern coding guidelines such as PSR-2. It = also saves time if you don't have to remove array keys of lists and convert= array() to [].=0A= > =0A= > =0A= > Trying to match any particular coding style seems rather outside the =0A= > remit of a built-in function - do we need flags for tabs vs spaces, =0A= > trailing commas, etc, etc? Surely it's simpler for users to take the =0A= > existing var_export format and use their IDE or dev scripts to re-format = =0A= > it to taste.=0A= =0A= =0A= Again, the IDE may have issues with the control characters in strings or un= expectedly remove or add them=0A= (e.g. windows vs unix newlines)=0A= =0A= For tabs vs spaces, Sara Golemon suggested an `'indent'` option=0A= where users could choose what string prefix to use as spaces/tabs,=0A= but I feel this would increase the initial scope of the RFC too much.=0A= =0A= For a new developer, they may not have those features or plugins installed = in their IDE,=0A= or may not be aware of the existence of the shortcut/command to invoke thos= e features on a range.=0A= (phpcbf, or for reindenting Ctrl+space in eclipse, `=3D` in vim, etc.)=0A= Additionally, scripts to reindent may not remove the `0 =3D>`, `1 =3D>`, et= c,=0A= either not containing a php parser or assuming the user deliberately added = those keys.=0A= =0A= It would be much easier to reindent the output of var_representation than t= o rewrite+reindent the output of var_export.=0A= =0A= =0A= Regards,=0A= Tyson=