php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Request #71896 break to end of block if error
Submitted: 2016-03-25 09:29 UTC Modified: 2017-08-04 23:03 UTC
Votes:1
Avg. Score:1.0 ± 0.0
Reproduced:0 of 1 (0.0%)
From: p dot peyremorte at free dot fr Assigned:
Status: Suspended Package: *General Issues
PHP Version: Irrelevant OS: all
Private report: No CVE-ID: None
Have you experienced this issue?
Rate the importance of this bug to you:

 [2016-03-25 09:29 UTC] p dot peyremorte at free dot fr
Description:
------------
Hi, 

I would like to propose to add a new instruction, like :
 
   break_if_empty(expression, command);

Description:

   If "expression" is empty(undef or false), then execute "command" and skip until end of current block = skip until next "}" at same level.


Explanation and example:

Each time we have some linear treatment, i.e. on response to POST request, errors can occurs that must stop the linear treatment and return an error message, but not stop all the script.

This produce many nested or successive checks of an "error flag"

Exemple :
if (isset($_POST[...])
{
  if (empty($_POST[...])
    $error = '... must not be empty';
  else  
  { init something;
    if (!mysql....) 
      $error = 'Cannot reach database';
    else
    {
     .....;
    }
  }

  if (empty($error))
  {
    if (someting wrong) 
      $error = 'wrong params';
  } 

  if (empty($error))
  {
     next steps...
  }
  etc ...
}

Such structure can be simplified by using function and "exit" or "return" but it requires to move the full bloc, and only it, in a function. All external variable must be passed as parameter or declared as global, inducing frequent miss or bug.


It can also be simplifyed using "goto", but not so much and most of us really dislike it :

if (isset($_POST[...])
{
  if (empty($_POST[...])
  {
    $error = '... must not be empty';
    goto EndBloc;
  }
 
  init something
  if (!mysql....)
  {
    $error = 'Cannot reach database';
    goto EndBloc;
  }
   .....;

  if (empty($error))
    goto EndBloc;
  
  next steps...

EndBloc:
}



With break_if_empty(), my first exemple would resume to :

if (isset($_POST[...])
{
  break_if_empty($_POST[...], $error = '... must not be empty');

  init something;

  break_if_empty(mysql....  , $error = 'Cannot reach database');

  .....;

  break_if_empty(someting wrong, $error = 'wrong params');

  next steps...

  etc ...
}

This is a lot easier to read, to understand and to maintain than first exemple.
:-)



Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2016-03-25 10:55 UTC] inefedor at gmail dot com
Or you could throw an exception or do an early return, eg:
if ( ! isset($_POST['field'])) {
    throw new InvalidInputException("field");
}

or:

if ( ! isset($_POST['field'])) {
    return new Result::error("Field error");
}

Or separate extract from your code input data validation library, database library and so on, where each of them would tell you if they had an error in some way (either with exceptions or return values)
 [2016-03-25 12:45 UTC] sven dot sauleau at xtuc dot fr
Hi,

If you're using an MVC pattern, you have too much logic in your controller.

I would recommend you to create services for each step.

Like this example:

if (isset($_POST[...])
{
  $error = service1($_POST[...], $error = '... must not be empty');

  if (!$error) {
  	$error = service2(mysql....  , $error = 'Cannot reach database');
  }

  if (!$error) {
  	$error = service3(someting wrong, $error = 'wrong params');
  }

  etc ...

  if (!$error) {
  	// End
  } else {
  	throw $error
  }
}

From my view the "break_if_empty" function will not be easier to read or understand since it's comparable to goto. It allows you to create spaghetti code the same way.
 [2016-03-25 12:46 UTC] nikic@php.net
-Package: PHP Language Specification +Package: *General Issues
 [2016-03-25 13:08 UTC] p dot peyremorte at free dot fr
-Package: *General Issues +Package: PHP Language Specification
 [2016-03-25 13:08 UTC] p dot peyremorte at free dot fr
Yes, there are others solutions, but none is so compact and simple.

break_if_empty() is intended to be similar of "break" (for loops only), applied to current block "{ ...}", to maintain structured programming inside it like in loops.

The add of the 2 parameters only enables most of the time to skip the require of new block "{ }". ("command" can be optional). 

It is exactely the same than (often used structure) :
  ....
  if (!expression)
  {
    [optionnal command;]
    goto End_of_block;
  }

  ....

EndOfBlock:
}
... <- continue here.

but in only 1 line of code.
 [2016-03-25 17:45 UTC] stas@php.net
-Package: PHP Language Specification +Package: *General Issues
 [2017-08-04 23:03 UTC] stas@php.net
-Status: Open +Status: Suspended
 [2017-08-04 23:03 UTC] stas@php.net
Thank you for your interest in PHP and for submitting a feature request. Please be aware that due to the magnitude of change this request requires, it would be necessary to discuss it on PHP Internals list (internals@lists.php.net) as an RFC. Please read the guide about creating RFCs here:
https://wiki.php.net/rfc/howto
If you haven't had experience with writing RFCs before, it is advised to seek guidance on the Internals list (http://php.net/mailing-lists.php) and/or solicit help from one of the experienced developers. 

Please to not consider this comment as a negative view on the merits of your proposal - every proposal which requires changes of certain magnitude, even the very successful and widely supported ones, must be done through the RFC process. This helps make the process predictable, transparent and accessible to all developers.
 
PHP Copyright © 2001-2017 The PHP Group
All rights reserved.
Last updated: Sun Nov 19 01:31:42 2017 UTC