Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:107657 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 73146 invoked from network); 24 Oct 2019 15:04:08 -0000 Received: from unknown (HELO php-smtp3.php.net) (208.43.231.12) by pb1.pair.com with SMTP; 24 Oct 2019 15:04:08 -0000 Received: from php-smtp3.php.net (localhost [127.0.0.1]) by php-smtp3.php.net (Postfix) with ESMTP id A92B02C2B7E for ; Thu, 24 Oct 2019 05:50:32 -0700 (PDT) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on php-smtp3.php.net X-Spam-Level: X-Spam-Status: No, score=-2.6 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_LOW, SPF_HELO_NONE autolearn=no autolearn_force=no version=3.4.2 X-Spam-ASN: AS3265 194.109.0.0/16 X-Spam-Virus: No Received: from lb2-smtp-cloud9.xs4all.net (lb2-smtp-cloud9.xs4all.net [194.109.24.26]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by php-smtp3.php.net (Postfix) with ESMTPS for ; Thu, 24 Oct 2019 05:50:31 -0700 (PDT) Received: from [IPv6:2001:983:6fc5:1:3cbd:5793:795b:352d] ([IPv6:2001:983:6fc5:1:3cbd:5793:795b:352d]) by smtp-cloud9.xs4all.net with ESMTPA id NcZRiu7BtsBskNcZSirUu1; Thu, 24 Oct 2019 14:50:31 +0200 To: Mike Schinkel , David Negrier Cc: internals@lists.php.net References: <1451C117-D656-472D-9FD0-642351300BD9@newclarity.net> Message-ID: <47e3fd4c-94ce-6b89-9a88-1b49ec21da0b@xs4all.nl> Date: Thu, 24 Oct 2019 14:50:28 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.9.0 MIME-Version: 1.0 In-Reply-To: <1451C117-D656-472D-9FD0-642351300BD9@newclarity.net> Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: 7bit X-CMAE-Envelope: MS4wfEqm4gR/OhO18EU2obxifc6ZIqd9gkC85f5JnLoXZTgkL8PX+twTcM06eYl5YrEioHYkyoXdNIxUYU7iKCO5LJbqAUYWAIf1D+VZaMphTedk80dyxddq qjGKZFLTPNLirv5y5lKoDahiaCXxQddXe5eke3Az7Hb2K+tN7eFBhq7SeL4KBewZFz4V90DZTKE5E8ffQKUV2n1XERNVtSdhW9kCRDK6nb5a1aqxsykZ227+ bXM8wCxThSLJPIjfAPqodhC4CY3W6G8wNBgFXXT/JIKi4qUXHU3GjVH64cI+HChDYUmX0z49qw7uimqxbo2b8U/KVo7GxdWF4Nv1L7S8kp0AqMCmutqJb1vp QhR1lwdP X-Envelope-From: Subject: Re: [PHP-DEV] Reclassifying some PHP functions warning as exceptions From: d.takken@xs4all.nl (Dik Takken) On 21-10-19 19:56, Mike Schinkel wrote: > The idea that functions that I could previously dealt with in four lines of code: > $filepath = __DIR__ . '/foobar.json'; > if (false === ($content = file_get_contents($filepath)) ) { > error_log( sprintf("failed to open '%s'", $filepath )); > return false; > } > Will potentially now requires me to add a second brace-enclosed block and two more lines of code and force me to handle varying exception classes causes me to cringe and will make me want to cry: > > $filepath = __DIR__ . '/foobar.json'; > try { > $content = file_get_contents( $filepath ); > } catch (Exception $exception) { > error_log( sprintf( "failed to open '%s'", $filepath ) ); > return false; > } > Indeed, surrounding the function call with try / catch is what you need to do when you want to retain the old behavior and convert the exception into a return value that indicates an error. However, you could also choose to leverage the new behavior of throwing exceptions to simplify your code. Passing the error condition to the caller can now be done by *not* handling the exception that is thrown, so: $filepath = __DIR__ . '/foobar.json'; if (false === ($content = file_get_contents($filepath)) ) { error_log( sprintf("failed to open '%s'", $filepath )); return false; } becomes: $content = file_get_contents($filepath) Here we assume that the exception contains an appropriate message allowing us to omit generating it manually. Of course, the caller will have to be adjusted to handle the exception in stead of the false. An IDE like PHPStorm will nicely point you at the places in your code that need to be adjusted. > Since I know that many in the PHP world believe that exceptions are a good thing, I understand that I will be unlikely to change everyone's mind and get them to start doing error handling as soon as they discover the error rather than just throw it and let some other code that doesn't have as much context deal with it. > > But my hope is at least PHP won't change to force having to use try/catch for practically every function call. Such a change might even be enough to finally get me to give up on PHP and move full time to Go because it will make coding in PHP so tedious. One could also reason the other way around. When a function returns some value or false in case of an error you have to check the return value for practically every function call. And we all forget to do so, resulting in unexpected failures. Exceptions allow us to simply use the return value without additional checks. Should anything go wrong calling the function we have plenty of options: * Just let it crash (which is the right thing to do in some cases) * Have a caller higher up in the call stack handle it * Surround the function call with a try / catch later, should we decide that we want to handle the problem locally anyway. > Just the other day I had to deal with the fact PhpStorm flags functions that return Exceptions if I don't handle them, and `new DateTime()` throws an Exception because it's optional parameter could cause a failure, even though I was not passing in any parameter. I had to wrap in my own `TryCatch()` function that basically just buries the Exception to get PhpStorm to stop complaining. You do not have to use a wrapper. Yes, PHPStorm nicely points you at a possible failure point in your code, which reminds you to think about how to handle them. You don't get that when a function returns false or null in case of error. When you get the code inspection warning, you can either: * Handle the exception * Pass the exception to the caller and add a @throws to the doc string * Suppress the inspection by using the following inspection hint: /* @noinspection PhpUnhandledExceptionInspection */ Since exceptions should mostly be used for situations where it is best to run for the emergency exit, wrapping a function call in a try / catch is not expected to be something done frequently. Regards, Dik Takken