based on #180137-26: Unsupported Operand Type

use type hinting on all function parameters

task to do:
1. create a coding standard
2. roll patches per module

Comments

robloach’s picture

I think we should only use type hinting is the argument assumes a certain type for the argument. l() in Drupal 6, for example, assumes that the $options argument is array. If you don't pass it an array, it will result in a PHP error:

function l($text, $path, $options = array()) {
  // Merge in defaults.
  $options += array(
      'attributes' => array(),
      'html' => FALSE,
    );

This is one example where type hinting really benefits because then it cleanly results in a PHP argument exception rather then an ugly PHP error.... Subscribing.

Anonymous’s picture

big +1 for this from me.

c960657’s picture

There seems to be different opinions on whether to write function foo(array $bar) or function foo(Array $bar). I suggest using the former, as this is the style used in the PHP manual page on type hinting. Also, the array() construct and the array type string use the lowercase variant. The most prominent exception I can find is print_r() that outputs Array( ... ).

Likewise I suggest using stdClass (this is written StdClass a few places in Drupal).

Anonymous’s picture

i agree with c960657. i work with Zend Framework, and it uses lowercase for type hinting array as well.

dave reid’s picture

Status: Active » Needs review
StatusFileSize
new23.07 KB

I also agree with #3. Here's an initial patch to standardize the capitalization of the current type hinting before I start searching for parameters that need type hinting.

pasqualle’s picture

Status: Needs review » Reviewed & tested by the community

patch in #5 does not change any functionality, so it is ready to go

pwolanin’s picture

Looking at the diff, I find Array $foo more readable than array $foo in differentiating the type hinting from actual parameters, so I'm not sure I agree with the proposed change.

robloach’s picture

I think the lower-case "array" makes more sense for the type hinting then the upper-case "Array". When creating a new instance of an array, Drupal coding standards ask for the lowercase:

  $myarray = array(1, 2, 3);

So why not bring that standard over to the type hinting as well? Either that, or also make the creation require the uppercase as well:

  $myarray = Array(1, 2, 3);

I think we should keep both the instantiation and type the same case. Either have both the type and the creation use lowercase, or uppercase, not both. Would also be good to get Crell's thoughts on this.

dave reid’s picture

I agree with Rob. It should be the same case as the coding standard. We shouldn't have two conflicting variable capitalization standard.

pwolanin’s picture

Yes, since Crell wrote most of those type hinting instances, I'd liek his input. As above - I don't claim it's consistent. Instead the difference as compared to instantiation (or casting) makes it more readable because it stands out.

david strauss’s picture

I prefer the lowercase "array" for type hints. It's consistent with our widespread use of "array()".

The readability improvement (if worthwhile) would be better implemented with a more radical change to parameter variable naming. I see no reason why the type hints should stand out in function definitions instead of the actual parameter variable names:

function my_func(array $One, $Two, array $Three) {
}

versus Peter's suggestion:

function my_func(Array $one, $two, Array $three) {
}

I'm not saying we should change the standard, just that I think there would be more effective approaches than Peter's.

dries’s picture

Status: Reviewed & tested by the community » Fixed

I'm also in favor of lower case. I committed Dave's patch. Thanks!

dave reid’s picture

Status: Fixed » Active

Setting this back to active to search for all the type-hinting needed now that we have a standard.

dave reid’s picture

Status: Active » Needs review
StatusFileSize
new34.51 KB

First pass with array type-hinting. My computer is too slow to run all tests, let's see how the testing bot fares.

dave reid’s picture

StatusFileSize
new37.66 KB

common.inc changes did not pick up...

Status: Needs review » Needs work

The last submitted patch failed testing.

dave reid’s picture

Title: type hinting all params » Add type hinting parameters
Status: Needs work » Needs review
StatusFileSize
new42.51 KB

Another round, actually can install now.

Status: Needs review » Needs work

The last submitted patch failed testing.

Crell’s picture

Status: Needs work » Needs review

I love how multiple people said that my input would be useful here and I didn't find out about the issue until after it was committed...

I discussed the case question with webchick months and months ago. I originally used capitals in DBTNG because in PHP the only things that can be type hinted are arrays and classes/interfaces. Classes/interfaces are always capitalized (in pretty much every convention, including Drupal core's now), so having all type hints be capitalized except for arrays didn't make much sense at all. It also made them stand out as different from array(), because they're a type hint, not a declaration. webchick agreed with that logic.

With that said, I don't care enough either way to make a huge fuss out of it. Lowercasing array is not wrong, just confusing when writing type hints. :-)

On the whole I am very +1 for adding more type hints, as they make the code more self-documenting and easier to debug since major errors will give a more useful error message. The caveats I will offer are:

1) Type hint all arrays iff we expect only an array, as is the case in l(). So by default don't type hint them unless you're sure. (I do plan to add more type hints to the DB layer once we get rid of the BC layer.)

2) Type hint classes/objects only with interfaces, not with actual class names. I know DBTNG violates that in a few places, but not many. :-) Type hinting to a class means you can only "fudge it" if you subclass from the parent class, which is not always possible. If you type hint to an interface, then you can pass in any object regardless of its hierarchy that implements that interface. That's much more flexible. See the changes made to DatabaseStatement in order to make the SQLite driver possible for a good example.

david strauss’s picture

@Crell In standard C++ and Java code, primitives are lowercase and classes are camelcase. In PHP, arrays are primitives, so we would not be breaking with longstanding convention by keeping "array" lowercase yet preserving the camelcase of class names in hints.

Crell’s picture

Status: Needs review » Needs work

Hm, I crossposted with the bot.

drewish’s picture

subscribing.

dave reid’s picture

pasqualle’s picture

related issue, where type hinting can not be used: #351898-13: Database API is not E_STRICT compatible

lilou’s picture

Issue tags: +Coding standards

Add tag.

sun’s picture

Lovely patch. Was this manually crafted or automated in some way? (re-roll?) :)

Crell’s picture

I think if this is going to happen it will have to be piecemeal. And I'm fairly sure the last patch here isn't even close to applicable anymore. :-)

naught101’s picture

StatusFileSize
new691 bytes

Here's another piece for the meal. entity_load() does strange strange things if it's $ids isn't an array.

Crell’s picture

Status: Needs work » Needs review

Status: Needs review » Needs work

The last submitted patch, entity_load-type_hinting-0.patch, failed testing.

jbrown’s picture

Version: 7.x-dev » 8.x-dev

This needs to be documented here: http://drupal.org/coding-standards#functdecl

johsw’s picture

Issue tags: +Type Hinting

@jbrown I've posted an issue here: http://drupal.org/node/1158720

jbrown’s picture

@Crell if no interface exists, does it make sense to type hint with the class name?

Crell’s picture

I'd lean no. Hinting with the class name means that you cannot, ever, pass a variable that is not that class or a child of that class. There may be exceptions to that, but I'd prefer to never strong-type on a class.

You can, however, still specify the class type in the DocBlock. I don't know how many IDEs would pick up on that for auto-complete, but at least a human reader can pick up on it.

robloach’s picture

Hinting with the class name means that you cannot, ever, pass a variable that is not that class or a child of that class

Isn't that the desired result? If we expect a certain interface to be passed, then we expect a class that implements that interface to be passed in. An example of type hinting with interfaces is around, which shows that it works with interfaces, but gives you an error if you're trying to pass in a variable that does not implement the interface (desired result).

I think we should refine this issue to hit just functions where we expect arrays, and then a new issue where we add type hinting for classes. We don't want to implement that bike shed interface.

jbrown’s picture

Title: Add type hinting parameters » Type hint array parameters

Good idea Rob!

Crell’s picture

Agreed on narrowing this issue's focus.

Rob: The problem with strong-typing on classes is if you want to have a class that implements two different interfaces (so it satisfies two different strong types), you're fine. If you want to have a class that extends from two different classes (because no interface is provided), you're screwed. It limits the amount of flexibility you have more than you probably intend. Strong typing in PHP should really only be used to say "I am going to use this object this way, so it better be ready for it". That's interfaces. Classes are for implementation details, which if you care about, you're doing it wrong. :-)

robloach’s picture

Issue tags: +PHPWTF

... for serious ;-) .

jbrown’s picture

I think permitting flexibility without defining an interface is a bad idea.

robloach’s picture

Status: Needs work » Needs review
Issue tags: -PHPWTF
StatusFileSize
new38.25 KB

We might want to split this into a different issue for each include file, but we'll see.

lars toomre’s picture

If we are adding type hinting to the function definitions, can we at the same time add the same type hinting to @param directives? Would you like me to roll an updated patch for that part?

lars toomre’s picture

@Rob I also noticed that you only added array type hinting to function variables with a default of array(). Shouldn't we also add array type hinting to the various form functions that use $form and $form_state?

robloach’s picture

Was concerned about the scope. Didn't want to do too much in one patch. Think the form changes should be a different issue, or hit those in here too?

If you wanna re-roll, be my guest! :-)

lars toomre’s picture

StatusFileSize
new52.83 KB

This is an untested patch that takes @rob's work from #41 and adds what I believe are other array declarations and @param type hinting that occurs in includes A through bootstrap.inc. I am curious what the bot and others think before I continue to common.inc and the rest of the includes directory.

lars toomre’s picture

It looks like patches in both #41 and #45 are having some of sort of test bot issue. Any ideas??

lars toomre’s picture

@Rob Loach and others - I created a patch in #1800330-2: Add missing type hinting to System module docblocks that adds type hinting to the *api.php files in the System module. There are considerable array definitions there like there are here. I would appreciate some reviews there to get that committed. Thanks.

Status: Needs review » Needs work

The last submitted patch, 318016-44-array-th.patch, failed testing.

mgifford’s picture

Is there a plan to revisit this before release or should this get bumped to D9?

lars toomre’s picture

This needs to be done... Core committers did not want to touch issues like this that touch many files while there are a lot of potentially conflicting patches being worked on.

mgifford’s picture

Is there any way to tag it to see that it is dealt with properly before launch? Should the priority be bumped? Or am I worrying about something that's already taken care of?

Crell’s picture

This should be done piecemeal. First, by ensuring that any NEW patches that touch code that should be type hinted get type hinted, and second by doing probably file-at-a-time or module-at-a-time patches. That's the only way this is going to happen.

The WSCCI initiative is working on the big task of converting all page callbacks to controllers at present, with some refactoring along the way. That's an excellent set of patches to review specifically for this issue.

Version: 8.0.x-dev » 8.1.x-dev

Drupal 8.0.6 was released on April 6 and is the final bugfix release for the Drupal 8.0.x series. Drupal 8.0.x will not receive any further development aside from security fixes. Drupal 8.1.0-rc1 is now available and sites should prepare to update to 8.1.0.

Bug reports should be targeted against the 8.1.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

  • Dries committed 55382d0 on 8.3.x
    - Patch #318016 by Dave Reid: step one to standardizing type-hinting.
    
    

  • Dries committed 55382d0 on 8.3.x
    - Patch #318016 by Dave Reid: step one to standardizing type-hinting.
    
    

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.9 was released on September 7 and is the final bugfix release for the Drupal 8.1.x series. Drupal 8.1.x will not receive any further development aside from security fixes. Drupal 8.2.0-rc1 is now available and sites should prepare to upgrade to 8.2.0.

Bug reports should be targeted against the 8.2.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

  • Dries committed 55382d0 on 8.4.x
    - Patch #318016 by Dave Reid: step one to standardizing type-hinting.
    
    

  • Dries committed 55382d0 on 8.4.x
    - Patch #318016 by Dave Reid: step one to standardizing type-hinting.
    
    

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.6 was released on February 1, 2017 and is the final full bugfix release for the Drupal 8.2.x series. Drupal 8.2.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.3.0 on April 5, 2017. (Drupal 8.3.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.3.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.6 was released on August 2, 2017 and is the final full bugfix release for the Drupal 8.3.x series. Drupal 8.3.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.4.0 on October 4, 2017. (Drupal 8.4.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.4.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.4 was released on January 3, 2018 and is the final full bugfix release for the Drupal 8.4.x series. Drupal 8.4.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.5.0 on March 7, 2018. (Drupal 8.5.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.5.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.6 was released on August 1, 2018 and is the final bugfix release for the Drupal 8.5.x series. Drupal 8.5.x will not receive any further development aside from security fixes. Sites should prepare to update to 8.6.0 on September 5, 2018. (Drupal 8.6.0-rc1 is available for testing.)

Bug reports should be targeted against the 8.6.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.6.x-dev » 8.8.x-dev

Drupal 8.6.x will not receive any further development aside from security fixes. Bug reports should be targeted against the 8.8.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.9.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

  • Dries committed 55382d0 on 9.1.x
    - Patch #318016 by Dave Reid: step one to standardizing type-hinting.
    
    
jungle’s picture

Issue summary: View changes
Status: Needs work » Needs review
Issue tags: +Needs issue summary update

Should this mark as fixed? Or the IS should be updated at least for me. Rolling patches per module is not applicable according to the scope police. https://www.drupal.org/core/scope#files

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.7 was released on June 3, 2020 and is the final full bugfix release for the Drupal 8.8.x series. Drupal 8.8.x will not receive any further development aside from security fixes. Sites should prepare to update to Drupal 8.9.0 or Drupal 9.0.0 for ongoing support.

Bug reports should be targeted against the 8.9.x-dev branch from now on, and new development or disruptive changes should be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

andypost’s picture

Version: 8.9.x-dev » 9.2.x-dev
quietone’s picture

I agree with jungle that can be closed. Work on coding standards continues in #2571965: [meta] Fix PHP coding standards in core, stage 1.

quietone’s picture

Status: Needs review » Closed (duplicate)

An early version of this patch was committed on 2008, #13 and then reopened when a standard was agreed to. Now, coding standard changes are done by each sniff and there is an issue for type hints, #3107000: Fix Drupal.Commenting.FunctionComment.TypeHintMissing.

This patch contains coding standard fixes that apply to more than one sniff such as #2903911: Fix 'Drupal.Commenting.FunctionComment.ParamMissingDefinition' coding standard. There are also code changes to function user_role_permissions($roles = array()) { which look to be implemented in the meantime or otherwise handled because permissions are now config.

So, I think this can be closed as a duplicate and work continue in #3107000: Fix Drupal.Commenting.FunctionComment.TypeHintMissing.

quietone’s picture