Req #67171 [NEW]: Object Notation (like mysqli::fetch_object)

From: Date: Thu, 01 May 2014 18:02:08 +0000
Subject: Req #67171 [NEW]: Object Notation (like mysqli::fetch_object)
Groups: php.bugs 
Request: Send a blank email to php-bugs+get-185553@lists.php.net to get a copy of this message
From:             fleshgrinder at gmx dot at
Operating system: 
PHP version:      Irrelevant
Package:          Unknown/Other Function
Bug Type:         Feature/Change Request
Bug description:Object Notation (like mysqli::fetch_object)

Description:
------------
It would be great to see something like the new array notation for
objects as well, as it would greatly improve writing easy to understand
code and allow IDEs to help developers write code faster. I was thinking
about this for some time and I think I came to a solution that would
meet these requirements, now it would only need somebody who knows how
to implement this in PHP.

We already have the new array syntax, like in JavaScript:

$array = [ "key" => "value" ];

To generate an object from the array one has to do the following:

$object = (object) [ "key" => "value" ];

It would be great if this could be shortened to the following (like in
JavaScript):

// Of course the syntax doesn't matter, but read on why I wrote it like
this.
$object = { $key => "value" };

This would result in an \stdClass instance:

var_dump($object);
object(stdClass)#1 (1) { ["key"]=> string(5) "value" }

This would already be an improvement, as one can now easily enable IDE
users with auto-completion:

/* @var $object \MyStubClass */
$object = { $key => "value" };

But we could even go a step further with this and allow something like
the following:

class Foo {

  /**
   * Documentation that is displayed in IDEs.
   *
   * @var string
   */
  public $property1;

  /**
   * Documentation that is displayed in IDEs.
   *
   * @var string
   */
  public $property2;

  /**
   * Not accessible!
   */
  protected $protectedProperty;

  /**
   * Not accessible!
   */
  private $privateProperty;

}

$foo = {\Foo
  $property1 => "value",
  $property2 => "value",
};

var_dump($foo);

object(Foo)#1 (2) { ["property1"]=> string(5) "value"
["property2"]=>
string(5) "value" } 

# Where's the benefit?

Well, imagine something like Drupal's Form API
https://api.drupal.org/api/drupal/developer!topics!forms_api_reference.html/8
where you have to pass associative arrays with various offsets. You'll
have absolutely no clue what offsets are available to you if you don't
have the documentation page available. With the above, this wouldn't be
any problem. See the "Test script" section for a real world Drupal Form
API example that would greatly help any developer who uses an IDE.

# Why do you propose this exact syntax?

Defining the class name directly after the opening curly brace should be
easy to parse, because you'll always get the {\ combination which should
be pretty unique.

The dollar before the keys is used for IDEs, so that they know that this
supposed to be an existing property within the class. This would allow
proper auto-completion support for properties, e.g. {\Foo $ and now if
we hit Ctrl + Space the IDE kicks in (or it kicks in after its own time
out, doesn't matter).

The => combination was only used because developers are already used to
it from arrays since many, many years. Of course the JavaScript syntax
would be a valid alternative and faster to write (e.g. { $key: "value"
});

It's important to note the last comma I included in all examples, as we
know it from arrays. This has to work to minimize errors and mistakes,
like with arrays.

# Anything else?

The whole thing should work like mysqli::fetch_object() by setting the
properties to their values BEFORE calling the classes __constrcut()
method. Of course this also means that we need the possibility to pass
properties to the __construct() method.

class Bar extends Foo {

  public function __constrcut($mandatoryParam) {}

}

$bar = {\Bar
  $property1 => "value",
  $property2 => "value",
}("mandatory param value");

This would (again) allow IDEs to auto-complete. The fact that the braces
are left out if no parameters should be passed to the __constrcut()
method is no problem, in fact it's even identical to the new keyword
usage...

new Foo;

new Foo();

... are equivalent.

PS: I don't really know if this is the right place to post this kind of
huge feature request, or if the developer mailing list would have been
better. But there is that "Feature Request" option and well, what is it
for if not for feature requests.

PPS: Can't wait to hear your feedback!

Test script:
---------------
// We want to create a <code>"text_format"</code> form element in Drupal
8.
//
// Usually that would look like this (with the new array syntax):

$form['body'] = [
  "#type"          => "text_format",
  "#title"         => t("Body"),
  "#default_value" => $body->value,
  "#format"        => $body->format,
  "#weight"        => 0,
];

// With the proposed syntax, the CMS could declare a class first:

namespace \Drupal\FormElement {

  abstract class AbstractFormElement {

    public $type;

    public $title;

    public $defaultValue;

    public $description;

    public $attributes = [];

    public $required = false;

    public $tree = false;

    public $parents = [];

    public $weight;

  }

  class Textarea extends AbstractFormElement {

    public $type = "textarea";

    public $cols = 60;

    public $resizeable = true;

    public $rows = 5;

    // Automatically instantiated when this class is instantiated!
    public $ajax = {\Drupal\Form\Event $event => "blur" };

  }

  class TextFormat extends AbstractFormElement {

    public $type = "text_format";

    public $format;

  }

}

// As you can see it's easy to define default values and easy for a
developer
// to comprehend where which property is coming from, which default
value it
// has, etc. etc.. Plus we could also provide documentation for each
property
// directly within the class and the developer has proper documentation
at his
// finger tips if using a real IDE.

// Let's continue and create the same form element as we did before, but
now
// with the new syntax.

$form['body'] = {\Drupal\FormElement\TextFormat
  $title        => t("Body"),
  $defaultValue => $body->value,
  $format       => $body->format,
  $weight       => 0,
};

// See how we could even leave out the first offset, because it's
already pre-
// filled in the class. Plus it's now a real instance of {@see
\Drupal\FormElement\TextFormat}
// which means that type hints will work.


-- 
Edit bug report at https://bugs.php.net/bug.php?id=67171&edit=1
-- 
Try a snapshot (PHP 5.4):   https://bugs.php.net/fix.php?id=67171&r=trysnapshot54
Try a snapshot (PHP 5.5):   https://bugs.php.net/fix.php?id=67171&r=trysnapshot55
Try a snapshot (trunk):     https://bugs.php.net/fix.php?id=67171&r=trysnapshottrunk
Fixed in SVN:               https://bugs.php.net/fix.php?id=67171&r=fixed
Fixed in release:           https://bugs.php.net/fix.php?id=67171&r=alreadyfixed
Need backtrace:             https://bugs.php.net/fix.php?id=67171&r=needtrace
Need Reproduce Script:      https://bugs.php.net/fix.php?id=67171&r=needscript
Try newer version:          https://bugs.php.net/fix.php?id=67171&r=oldversion
Not developer issue:        https://bugs.php.net/fix.php?id=67171&r=support
Expected behavior:          https://bugs.php.net/fix.php?id=67171&r=notwrong
Not enough info:            https://bugs.php.net/fix.php?id=67171&r=notenoughinfo
Submitted twice:            https://bugs.php.net/fix.php?id=67171&r=submittedtwice
register_globals:           https://bugs.php.net/fix.php?id=67171&r=globals
PHP 4 support discontinued: https://bugs.php.net/fix.php?id=67171&r=php4
Daylight Savings:           https://bugs.php.net/fix.php?id=67171&r=dst
IIS Stability:              https://bugs.php.net/fix.php?id=67171&r=isapi
Install GNU Sed:            https://bugs.php.net/fix.php?id=67171&r=gnused
Floating point limitations: https://bugs.php.net/fix.php?id=67171&r=float
No Zend Extensions:         https://bugs.php.net/fix.php?id=67171&r=nozend
MySQL Configuration Error:  https://bugs.php.net/fix.php?id=67171&r=mysqlcfg



Thread (3 messages)

« previous php.bugs (#185553) next »