2

When attempting to use a class that exhibits a trait with an abstract method declared AND the abstract method is declared with a parameter that is of type reference to array

I am getting the following error:

PHP Fatal error: MyTrait and MyClass define the same property ($foo) in the composition of MyClass. However, the definition differs and is considered incompatible. Class was composed in MyClass

How to declare an abstract method in a trait in such a way as to require the exhibiting class to only accept an array reference as input parameter?

What is the appropriate syntax for the parameter to the array reference in both the Trait and the exhibiting class?

(updated) example:

<?php

const LOCATION_PRECISION = 7;
const LOCATION_LAT = '40.7591523';
const LOCATION_LNG = '-73.9777136';

trait Geocodes
{
    protected $recast = [];
    protected $precision = LOCATION_PRECISION;

    abstract function reCast(array &$payload);

}

class Location
{
    use Geocodes;

//FATAL: can't override here!
//protected $recast = [
//    'lat' => ['index' => 'lat', 'type' => 'double'],
//    'lng' => ['index' => 'lng', 'type' => 'double']
//];

protected $lat = LOCATION_LAT;
protected $lng = LOCATION_LNG;

public function __construct()
{
   $this->precision = LOCATION_PRECISION;
   $this->recast['lat'] = ['index' => 'lat', 'type' => 'double'];
   $this->recast['lng'] = ['index' => 'lng', 'type' => 'double'];
}

public function recast(array &$payload)
{
  foreach(array_keys($payload) as $key)
  {
      var_dump($payload);
      $api_key = $this->recast[$key]['index'];
      $api_type = $this->recast[$key]['type'];
      if(! array_key_exists($api_key, $payload))
            $payload[$api_key] = bcadd($payload[$key],0,$this->precision);
  }
}

public function getLat() { return $this->lat; }
public function getLng() { return $this->lng; }

}

$loc = new Location();
$payload = ['lat' => $loc->getLat(), 'lng' => $loc->getLng()];
$loc->recast($payload);

echo PHP_EOL.print_r($payload, 1).PHP_EOL;
windsor
  • 379
  • 4
  • 9
  • `[...] same property [...]` -> i see no properties in your code – Wes Sep 03 '16 at 16:01
  • @Wes, yes, but that is the error that comes out. The 'property' in this case is the method name. – windsor Sep 03 '16 at 16:29
  • @Ryan, ok, I will give a better code example, I was intending to try to simplfiy the question to it's bare essentials and I did not want to clutter up the code. But since it seems like it would be more helpful I will post a full and complete example. – windsor Sep 03 '16 at 16:31
  • @Paul, I will post a complete example in the next few minutes that you can run and see the error. Thanks – windsor Sep 03 '16 at 16:31

1 Answers1

0

Short answer is that the code snippet in the question above does demonstrate the correct way declare reference to an array as a parameter in an abstract function of a trait. It also shows the correct syntax for the concrete function declaration inside the exhibiting class.

The error which I was getting and which is reproduceable in the code snippet below occured because I was attempting to override a defined property of a trait in a property declaration inside an exhibiting class. It just so happened that the name of the property and the name of a method of the trait was the same, so kudos to @Wes for catching that even though the code example I posted was incomplete at the time.

here is a link to the code with non-working lines commented out. You can run the code without error, then uncomment the problem area and it should fail with the message in the original post.

windsor
  • 379
  • 4
  • 9