As per discussion on the drupal-devel list, this issue if for discussion and patch discussion related to the first point made about E_ALL compliance. See point 1 at:
http://drupal.org/node/34341

Please comment on the coding guideline, the book entry, and the patch(es) submitted.

I'll update the book page according to the discussion on this page.

Once the coding guideline is agreed upon on this very specific issue, and the first patch has been committed accordingly, further patches can be submitted here to solve all other similar problems.

Comments

beginner’s picture

Status: Active » Needs review
deekayen’s picture

We need guidelines on how to write E_ALL compliant code? Really? In the midst of all these surveys where people in the comments to the survey announcement are talking about drowing in documentation? The standard can't just be "write E_ALL compliant code" or "write E_STRICT..."? I don't think drupal.org is the place to be teaching PHP programming fundamentals.

beginner’s picture

I would tend to agree with you... I was merely following the suggestion made on the devel list.
People have been submitting patches for E_ALL for ages, in different issues, but none of them have been committed yet.
Is Dries against this whole idea, or is he waiting for us to do something we haven't done yet?
I followed the suggestion because all else has failed previously, so I was thinking that maybe that was what was missing: proper, clear guidelines, etc...

If a one liner in the handbook saying "Write E_ALL compliant code" is enough, I'd be very happy, because we'd be able to delete the handbook page I wrote, I wouldn't have to keep it up to date, etc.., and I'll get back to writing patches so that they get submitted ASAP.

So, what do you think would increase our chances to see our E_ALL patches committed?

deekayen’s picture

Dries should be the one to answer that question.

This might not be a reasonable request, but you wouldn't happen to have a list of your E_ALL/E_STRICT patches would you? I don't want to duplicate anything.

beginner’s picture

I have this one, but it needs review and possibly changes (I'm still learning how to do things):
http://drupal.org/node/28540#comment-49935

Meanwhile, could anyone comment on the patch attached to this issue:
1- is the diff format the proper one? Is it commitable?
2- is the code change appropriate?
if the answer to both is YES, please mark this issue as patch-> ready to be committed.
if not, tell me what I am doing wrong so I can learn.

Thanks.

dries’s picture

Status: Needs review » Fixed
beginner’s picture

Status: Fixed » Reviewed & tested by the community
StatusFileSize
new5.99 KB

12 more instances of the same.

beginner’s picture

StatusFileSize
new5.9 KB

re-roll to latest head.

killes@www.drop.org’s picture

Status: Reviewed & tested by the community » Needs work

doesn't apply anymore

beginner’s picture

Status: Needs work » Reviewed & tested by the community
StatusFileSize
new5.52 KB

the same, updated.

drumm’s picture

isset() is preferred to !empty():
- It is easier to read.
- isset() was benchmarked against array_key_exists() and won.

drumm’s picture

Status: Reviewed & tested by the community » Needs work
deekayen’s picture

Status: Needs work » Reviewed & tested by the community

...but isset() !== !empty() so you should really use what you need to test for.

deekayen’s picture

Status: Reviewed & tested by the community » Needs work

status was switched when I was typing my last message

Jaza’s picture

Status: Needs work » Needs review
StatusFileSize
new20.34 KB

I just re-installed Apache / MySQL / PHP on my dev machine, and I was wondering why many of the pages on my Drupal test site were taking a long time to load. Turns out that when I re-installed PHP, the php.ini 'error_reporting' value on my machine got set to 'E_ALL'. And because Drupal currently has so many E_NOTICE level errors, it was increasing my page load time from 'virtually instant' to 'up to 10 secs'.

So this is a patch that I developed, to get rid of a whole lot of E_NOTICE errors relating to value checks that need an isset() or empty() check. This patch is not related to the other patch that's pending in this thread, but it is very similar. I didn't realise that there was already a pending patch here, or I would have developed my patch on top of it. Sorry about that.

Most of the problems that I found were in the FAPI, which seems to be a big troublemaker for generating 'undefined index / variable' errors. This patch removes all errors from most of the top-level admin pages on a standard Drupal 4.7 install. Cleaning this up is important, IMO, not just for the principle of having cleaner code, but also to improve performance for people who are stuck with E_ALL error reporting on their servers, and who currently have to put up with unnecessary lag on a lot of pages.

chx’s picture

As PHP does not provide a sane construct for $foo['bar'] or 'default' to accomplish the same, we need to write a monster of the code. And what do we gain by this bloating? So, very strong -1

webchick’s picture

A very strong +1 to counter chx's -1 ;) I'll try and review/test this later in the week.

chx’s picture

I take it back. It seems that php.ini-recommended has E_ALL. I still think this is pointless but I take back my -1 . Let bloated code flourish.

Crell’s picture

If the only way for you be E_ALL compliant is to have isset() scattered all over your code, it's a sign that you're doing something wrong in the first place. It's one reason why I try to avoid NULL values except as explicit function parameter defaults in general.

Big +1 to making Drupal E_ALL compliant. That's simply good coding practice, in any language.

However, -1 to doing it by having a zillion isset() calls in a zillion functions. A better alternative is to ensure that by the time a data structure gets to somewhere interesting, all necessary values have an actual value, even if it's some understood "not specified" value (eg, empty string or 0). Obviously there are exceptions, but generally you want to deal with the problem early on, not punt and let every function figure it out for itself.

beginner’s picture

StatusFileSize
new732 bytes

I started this thread because I belong to the group of developers who would like to see Drupal fully E_ALL compliant.

Drupal and E_ALL compliance

There are three groups of developers.

  1. Many would like Drupal to be E_ALL compliant.
  2. Most can't be bothered and won't help with this issue without actually being against.
  3. Few if any are categorically against E_ALL compliance ('bloated code'?).

It's up to the first group of people to make it happen.
The problem is manyfold:

  1. Regardless of Drupal's code numerous qualities, it is a sad mess with regard to declaring variables: there is a lot of mess to clean!
  2. More mess is being added everyday as patches and new functionality are being committed to core. So, if we want to clean Drupal of E_ALL notices, we need to have fixes committed faster than new sources of E_ALL notices are being introduced
  3. There is no clear vision or understanding among developers (of the first group) on how to actually solve the problem.
  4. There is a lot to fix, but at the same time, large patches are very unlikely to get committed (especially lacking serious review). The best we have achieved so far is a only line patch being committed (#6) and Dries set the issue as 'fixed' (??). Way to go!! ;)

Note that the purpose of this thread was precisely to figure out the way to solve the problem.

Important note on methodology

I still hope that Jaza's patch can get committed but it has little chance because of its size and even less lacking serious review by trusted core developers (i.e. not me). More importantly, not every one agrees on the exact fix (see above #11, #13, #19).

Note the link to the handbook page at the top of this issue: our first aim is to create a very definite policy with regard to coding style and how to solve error notices in different situations. Once such a coding policy has been set and agreed by the core commiters, they then can (and should) refuse a patch if it doesn't comply with the policy (which should solve the second of my list of problems above).

Since the errors are all over the place, we also need to proceed methodologically.
Here is the procedure I propose to follow:

  1. Make a clean install of Drupal cvs.
  2. Create your admin account then go straight to admin > modules and turn OFF all non-required modules, leaving us with a bare-bone install.
  3. In includes/common.inc change the line if ($errno & (E_ALL ^ E_NOTICE)) { to : if ($errno & (E_ALL)) which will allow you to experience the mess :)
  4. Click on the admin > settings link and start debugging the notices, one at a time, starting from the first one on the list!
  5. Get a fix for the first error notice committed.
  6. Get a coding policy relevant to that first fix firmly establish and enforced by core commiters.
  7. Rince and repeat.
  8. ???
  9. ...
  10. $$$!!

First notice on the list

Following the procedure outlined above, the first notice on admin/settings is:
notice: Undefined index: #processed in includes/form.inc on line 396.
which appears 5 times on this page.

The attached patch is the same fix as proposed in Jaza's patch above.
Crell has a point, though: who has a better fix?

beginner’s picture

Our first notice seems to be a rather arcane one...

http://api.drupal.org/api/HEAD/file/developer/topics/forms_api_reference...
says:

#processed :
INTERNAL. Used to ascertain whether or not a form element has been processed (ie: expanded to multiple elements).

The key '#processed' occurs only three times in the whole Drupal code.

Many other notices are about undefined array indices.
I don't see any place in the code where the form is being initialized with default values given for each index.

As Crell pointed out, maybe a more comprehensive solution would be to enforce a declaration of the variables earlier on in the code.
I'm not familiar with form.inc. Can someone help out?

beginner’s picture

StatusFileSize
new767 bytes

I tried adding '#processed' => FALSE) in modules/system.module:
$type['checkboxes'] = array('#input' => TRUE, '#process' => array('expand_checkboxes' => array()), '#tree' => TRUE, '#processed' => FALSE);
but it didn't work.

It seems that form_builder() IS the place I was looking for to initialize the form elements, at least in this case.
The new patch is an alternative way to fix the same problem as in patch #20. #20 is safer, as I am sure it won't break anything. This one needs proper review, but may be a better solution.

Comments?

drumm’s picture

Status: Needs review » Needs work

I'd like to see this happen, but please put different patches in different issues. A whole 20k of patch is up there and unfindable. Decide what you want to do with this issue and open another if you don't merge them.

beginner’s picture

Status: Needs work » Needs review

Yes. see my important, longish comment #20.
The topic of this issue is precisely to agree on how to make that happen.
patch #15 is currently out, because it is long, will probably never be properly reviewed, and there no agreement yet on how to fix the issues.

The patch needing review now is the one in #22.
Patch #20 fixes exactly the same problem but with a different approach, so #20 and #22 can be compared.

As per Crell's good comment #19, I'd say +1 for patch #22.
If others agree, that's the one to commit.

drumm’s picture

Status: Needs review » Needs work

> wget -qO - http://drupal.org/files/issues/e_all_admin-settings-1-alternative.diff.txt | dos2unix | patch -p0
patching file includes/form.inc
patch: **** malformed patch at line 18:

beginner’s picture

Status: Needs work » Needs review
StatusFileSize
new696 bytes

Hmm. Sorry for the corrupt patch file.
I tested this one and it works.
(otherwise, it's the same as #22 above).

drumm’s picture

Committed to HEAD.

drumm’s picture

Status: Needs review » Fixed
killes@www.drop.org’s picture

also to 4.7

beginner’s picture

Status: Fixed » Active

why fixed?
There are many more to go :)

For the record the #26 approach (declaring a default value early on) won over that of #20 (use of isset()).

Comment in #20 still applies.

beginner’s picture

next on admin/settings is:

notice: Undefined offset: 0 in includes/form.inc on line 886.
beginner’s picture

Status: Active » Needs review
StatusFileSize
new815 bytes

The same error appears 10 times on that page, i.e. once for each radio setting.

We're back to the use of isset(). I don't see a better solution now, but there could be.

beginner’s picture

StatusFileSize
new985 bytes

Here is the unmodified block of code in question:

/**
 * Roll out a single radios element to a list of radios,
 * using the options array as index.
 */
function expand_radios($element) {
  if (count($element['#options']) > 0) {
    foreach ($element['#options'] as $key => $choice) {
      if (!$element[$key]) {
        $element[$key] = array('#type' => 'radio', '#title' => $choice, '#return_value' => $key, '#default_value' => $element['#default_value'], '#attributes' => $element['#attributes'], '#parents' => $element['#parents'], '#spawned' => TRUE);
      }
    }
  }
  return $element;
}

I don't see other solutions for this one, because the code relies on the key NOT existing in order to create the proper radio element in the form.

The form makes use of the key #spawned which is NOT documented in the form api reference:
http://api.drupal.org/api/HEAD/file/developer/topics/forms_api_reference...
#spawned is not used anywhere else in the code.

Jaza’s picture

There seems to be a general misconception in this thread, that the isset() and empty() functions are "bad", and should be avoided wherever possible. I would like to make it clear that neither of these functions is "bad", and that in many cases, it is better PHP coding practice to use them, than it is to use plain boolean checking.

PHP is a loosely typed language, and nothing about PHP is looser than its type comparison and its boolean checking. The isset() and empty() functions exist to provide more strict and reliable mechanisms for this - don't be afraid to take advantage of them!

A few general rules that I follow:
- Variables should always be defined - even as NULL.
- It is OK to have undefined array elements, if you first check for their existence using isset($array[$index]).
- If you need to check for NULL values, use isset().
- If you need to check for NULL or empty non-string values (e.g. ints, arrays), use empty().
- If you need to specifically check for empty or NULL strings, use isset() in conjunction with $str !== '' - don't use empty(), as the string '0' is considered empty.
- If you can guarantee that the variable is never NULL, and you don't know what type it is, use plain boolean and strict boolean checking.
- If you can guarantee that the variable is never NULL, and you know what type it is, then use empty() for arrays, plain boolean checking for numbers, and strict boolean checking for strings.

As you can see, there are many times (in my books, at least) when plain boolean checking is not the right option. The PHP type comparison table has all the details, and is an invaluable reference for all of this.

drumm’s picture

Status: Needs review » Fixed

Committed beginner's last patch to HEAD, minus the comment change, which I think was incorrect.

Please put documention somewhere in our handbook instead of here.

I've seen and applied a number of other patches for PHP notices in other issues. I think separte issues works better since we can review small pieces in parallel.

Anonymous’s picture

Status: Fixed » Closed (fixed)