Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:113979 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 1068 invoked from network); 6 Apr 2021 17:49:12 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 6 Apr 2021 17:49:12 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id B19D7180002 for ; Tue, 6 Apr 2021 10:48:14 -0700 (PDT) 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,HTML_MESSAGE,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2, SPF_HELO_NONE,SPF_NONE autolearn=no autolearn_force=no version=3.4.2 X-Spam-Virus: No X-Envelope-From: Received: from mail-qk1-f179.google.com (mail-qk1-f179.google.com [209.85.222.179]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Tue, 6 Apr 2021 10:48:14 -0700 (PDT) Received: by mail-qk1-f179.google.com with SMTP id c3so15850712qkc.5 for ; Tue, 06 Apr 2021 10:48:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=newclarity-net.20150623.gappssmtp.com; s=20150623; h=from:message-id:mime-version:subject:date:in-reply-to:cc:to :references; bh=Ksp0Hpkh9EV3Iif58zRY5sadfZXrgruLj/HTRLgfgXo=; b=lpYggAMc/8r63FWPaMYrfSxSWutHZdESRbo4t1XfTHMAwuC3Io3VaX5fCM64BAheCM FAmPXIG1FWOw+X2FM4cTA23N/zOoBjmrdK8gq5LxcO+e5Un6tHEao/97X44294MEKVHo waOVOClocXC9nEpZ3GGo0PnPhlQR9zY/pUi2IiKp1EkmGNDO3Q1uynZ6lVhW1BLxdtuo y7xTaFReRsF7EZFlEssLE/Tz1Xe8jiEGpyaUDuaMzVgxIrk+UpY7bT6fR6rPKSK06SS0 gNrLyGMpOg0PkpJJM6sufoDyBDpcSQhmmVovidZNNcuX2+H8KBrMpIrmLHFylxzchjpw 8+3Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:message-id:mime-version:subject:date :in-reply-to:cc:to:references; bh=Ksp0Hpkh9EV3Iif58zRY5sadfZXrgruLj/HTRLgfgXo=; b=ATCKMvSqcqoEP+9X0OKVc83+9omFtjEXoioaP372cWAY46AFXDesbZRyy0SRKj9iSI ueH/Au/48x/aeHRtFpfVUMNRtTyuLs6G+YsOROiS588DilfH29BrcbAzsdBqX0koBN2/ 36qM8xXQgZ1FkZjWqblf/qokYX3wpmqyoemQ36ZS58aT3qTwrBrfZaP9GLwPumCgQUA8 6a33i30bFhoEqe0cnoxyoPHWuz2iY5DFk6Btv+K6K6dIl56NcNv0M4CWrF2nzaYg9/xw y0OUBzASoXilVMo58sCaHo+EPK5+w4ol++lobs3quXAiBjWYu3MLAe/51TqhelNDkxLC 9/aA== X-Gm-Message-State: AOAM5306/DxrgtUvHTGZ8oPrnrpKeI/sOuUk3+zdnAiiXU4jEqOaORQO LuhE2/3Yt7Ipcu7n5VLNktILTg== X-Google-Smtp-Source: ABdhPJxOyoIeMnZosHE6X2kw41dRA2DyR9581Q7t0IjjC1tv83esF8ESIs2Aw8YXuqSWdlmogbuYDA== X-Received: by 2002:a37:a8d3:: with SMTP id r202mr31928659qke.383.1617731291758; Tue, 06 Apr 2021 10:48:11 -0700 (PDT) Received: from [192.168.1.10] (c-24-98-254-8.hsd1.ga.comcast.net. [24.98.254.8]) by smtp.gmail.com with ESMTPSA id v2sm16144873qkv.39.2021.04.06.10.48.08 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Tue, 06 Apr 2021 10:48:09 -0700 (PDT) Message-ID: <9E723BDF-BCD5-4C07-A89E-9C7EAEB013B3@newclarity.net> Content-Type: multipart/alternative; boundary="Apple-Mail=_8A9734F7-1497-406A-811E-41CF43D86F00" Mime-Version: 1.0 (Mac OS X Mail 13.4 \(3608.120.23.2.4\)) Date: Tue, 6 Apr 2021 13:48:07 -0400 In-Reply-To: Cc: PHP Internals List To: Jesse Rushlow References: <0c5e70d7-5b11-5251-4ec9-608db63105c9@gmail.com> X-Mailer: Apple Mail (2.3608.120.23.2.4) Subject: Re: [PHP-DEV] Path forward for class_exists with different targeted PHP version implementations From: mike@newclarity.net (Mike Schinkel) --Apple-Mail=_8A9734F7-1497-406A-811E-41CF43D86F00 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=utf-8 > On Apr 5, 2021, at 9:00 PM, Jesse Rushlow wrote: >=20 > Sure thing - >=20 > In Symfony's MakeBundle we have a command "php bin/console = make:command". > This ultimately generates a "App\Console\XyzUserlandCommand::class" = that > allows the developer to customize in order to perform some task within > their app. e.g. run persistence operations, generate a backup, etc.. >=20 > What we do internally to generate that userland class is determine = which > features to include by checking the PHP version, dependencies = available, > etc.. As an example, when the user runs "make:command"; we check if = they > have PHP 8 && if "class_exists(Symfony\.....\Attributes::class)" - if = both > of those =3D=3D=3D true, we import the attribute class and generate = the needed > attributes for the command. Otherwise we would fall back to using > annotations if the user is running PHP 7. Where I ran into trouble was = the > Attributes::class (defines the attributes to be used in userland) = utilized > constructor property promotion (which is a pretty sweet addition to 8 = imo). >=20 > Up to this point if it's possible, we generally pick a > class/interface/method that introduces new functionality (Symfony > feature/bugfix) and call one of the \*_exists(class/method/interface) > functions in a conditional to determine if we can indeed use that = feature. > But because in this particular case the Attributes::class also uses > constructor property promotion, when calling > class_exists(Attributes::class) in PHP 7 we get: >=20 >=20 > ParseError: syntax error, unexpected 'public' (T_PUBLIC), expecting > variable (T_VARIABLE) >=20 > The work around was to "$canUseAttributes =3D 80000 <=3D = \PHP_VERSION_ID && \ > class_exists(AsCommand::class)" >=20 > All is fine and well, but this in my opinion, this feels like bad mojo = from > a developers standpoint. I must now need to be aware of the exact > implementation details of the object I'm checking before I can even = check > if it exists or not. I would expect any of the \*_exists() to tell me = if > the class/method/interface exists regardless of the implementation. My > first thought would be if the implementation is not compatible with = the PHP > version some sort of \RuntimeException::class would be thrown by PHP. = But > that is where my knowledge of PHP internals is disconnected from = developing > software in PHP. >=20 > I created a simple reproducer repo > https://github.com/rushlow-development/attribute-test (forgive the = repo > name, it really has nothing to do with attributes.) and for an even = simpler > example https://3v4l.org/4cMW4 >=20 > I apologize in advance for the wall of text - but I'm curious if there = is a > way to either improve our native functions, improve the docs, and/or = create > new functions for use cases like this. It is not clear to me exactly what you are asking for. It seems like = your use-case exists when loading code in an older version of PHP that = does not support newer features, right? If that is the case, the only "solution" =E2=80=94 which is obviously a = non-starter =E2=80=94 is to update older versions of PHP to be able to = gracefully fail when attempting to load a class designed for a newer = version of PHP to use. =20 OTOH if I misunderstand then can you clarify exactly what you are asking = for? -Mike >=20 > Thanks! > Jesse Rushlow >=20 > On Mon, Apr 5, 2021 at 3:30 PM Rowan Tommins > wrote: >=20 >> On 05/04/2021 18:14, Jesse Rushlow wrote: >>> I was attempting to use class_exists(UsesPropertyPromotion::class) = to >>> determine if an attribute implementation existed in order to = generate a >> PHP >>> 8 appropriate class - else fall back to generating a PHP 7 = appropriate >>> class. For context, this check was being written for Symfony's >> MakerBundle >>> which generates classes for Symfony projects. >>=20 >>=20 >> Hi Jesse, >>=20 >> Can you explain the use case in a bit more detail, perhaps giving = some >> example code you were hoping to write with class_exists()? >>=20 >> I suspect there are other ways to achieve what you were trying to do, >> but don't want to confuse things if I've misunderstood the = requirements. >>=20 >> Regards, >>=20 >> -- >> Rowan Tommins >> [IMSoP] >>=20 >>=20 --Apple-Mail=_8A9734F7-1497-406A-811E-41CF43D86F00--