Skip to content

Instantly share code, notes, and snippets.

@bastman
Created November 11, 2012 10:16
Show Gist options
  • Save bastman/4054380 to your computer and use it in GitHub Desktop.
Save bastman/4054380 to your computer and use it in GitHub Desktop.
chaining issues with php ide's: proper autocompletion/type hinting vs proper oop
<?php
/**
* a demo of current issues when working with chaining
* Looking forward to phpstorm 6
*
* @see: http://youtrack.jetbrains.com/issue/WI-2225
*
*
* file: chaining.php
* run: php chaining.php
*
* Created by JetBrains PhpStorm.
* User: VAIO
* Date: 11.11.12
* Time: 10:19
* To change this template use File | Settings | File Templates.
*/
class YouAreAwesome
{
/**
* @var string
*/
protected $you;
/**
* @var string
*/
protected $are;
/**
* @var string
*/
protected $awesome;
/**
* @var string
*/
protected $resultText;
/**
* @param string $value
* @return YouAreAwesome
*/
public function setYou($value = 'You')
{
$this->you = (string)$value;
return $this;
}
/**
* @param string $value
* @return YouAreAwesome
*/
public function setAre($value = 'are')
{
$this->are = (string)$value;
return $this;
}
/**
* @param string $value
* @return YouAreAwesome
*/
public function setAwesome($value = 'awesome')
{
$this->awesome = (string)$value;
return $this;
}
/**
* @return YouAreAwesome
*/
public function render()
{
$this->resultText = implode(
' ',
array(
$this->you,
$this->are,
$this->awesome,
)
);
return $this;
}
/**
* @return YouAreAwesome
*/
public function write()
{
echo (string)$this->resultText . PHP_EOL;
return $this;
}
}
class YouAreAwesomeNinja extends YouAreAwesome
{
/**
* @var string
*/
protected $ninja;
/**
* @param string $value
* @return YouAreAwesomeNinja
*/
public function setNinja($value = 'Ninja')
{
$this->ninja = (string)$value;
return $this;
}
/**
* @override
* @return YouAreAwesomeNinja
*/
public function render()
{
$this->resultText = implode(
' ',
array(
$this->you,
$this->are,
$this->awesome,
$this->ninja,
)
);
return $this;
}
}
class YouAreAwesomeNinjaFixIdeIssues extends YouAreAwesomeNinja
{
/**
* @param string $value
* @return YouAreAwesomeNinjaFixIdeIssues
*/
public function setYou($value = 'You')
{
return parent::setYou($value);
}
/**
* @param string $value
* @return YouAreAwesomeNinjaFixIdeIssues
*/
public function setAre($value = 'are')
{
return parent::setAre($value);
}
/**
* @param string $value
* @return YouAreAwesomeNinjaFixIdeIssues
*/
public function setAwesome($value = 'awesome')
{
return parent::setAwesome($value);
}
/**
* @param string $value
* @return YouAreAwesomeNinjaFixIdeIssues
*/
public function write()
{
return parent::write();
}
/**
* @param string $value
* @return YouAreAwesomeNinjaFixIdeIssues
*/
public function setNinja($value = 'Ninja')
{
return parent::setNinja($value);
}
/**
* @param string $value
* @return YouAreAwesomeNinjaFixIdeIssues
*/
public function render()
{
return parent::render();
}
}
// ============ here we go ==================
ini_set("display_errors", true);
error_reporting(E_ALL | E_STRICT & ~E_NOTICE);
set_error_handler(function($errno, $errstr, $errfile, $errline)
{
throw new \ErrorException($errstr, 0, $errno, $errfile, $errline);
});
// ==== simple chaining ===================
$youAreAwesome = new YouAreAwesome();
// beautiful code; easy to read
$youAreAwesome
->setYou('You')
->setAre('are')
->setAwesome('awesome')
->render()
->write()
;
// ==== extended chaining ===================
$youAreAwesomeNinja = new YouAreAwesomeNinja();
// beautiful code; easy to read - but ide type hinting fails!
$youAreAwesomeNinja
->setYou('You')
->setAre('are')
->setAwesome('awesome')
->setNinja('ninja') // ide: 'method not found in class!'
->render()
->write()
;
// ==== extended chaining: help my ide ===================
$youAreAwesomeNinjaFixIdeIssues = new YouAreAwesomeNinjaFixIdeIssues();
// beautiful code; easy to read - but ide type hinting fails!
$youAreAwesomeNinjaFixIdeIssues
->setYou('You')
->setAre('are')
->setAwesome('awesome')
->setNinja('ninja') // ok, no error shown by ide
->render()
->write()
;
// Right, we fixed that ide issue,
// by overriding all methods that return the class instance to be chained
// BUT THAT IS NOT THE IDEA OF PROPER OOP !!!!!!!
// == Another tiny issue with chaining, how about quick n dirty debugging? ====
// without chaining, I can easily dump each step
$youAreAwesome = new YouAreAwesome();
// var_dump($youAreAwesome); //just uncomment to debug
$youAreAwesome->setYou('you');
// var_dump($youAreAwesome); //just uncomment to debug
$youAreAwesome->setAre('are');
// var_dump($youAreAwesome); //just uncomment to debug
$youAreAwesome->setAwesome('awesome');
// var_dump($youAreAwesome); //just uncomment to debug
$youAreAwesome->render();
// var_dump($youAreAwesome); //just uncomment to debug
$youAreAwesome->write();
// ANYWAY: chaining is nice, escpecially if my ide supports that.
// Looking forward to phpstorm 6
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment