How to find default value of extend class method - php

i would like to define new class with extends of PDOStatement and in this child class i need override function bindColumn (PDOStatement::bindColumn) and in this override function call parent::bindColumn(). But i can't find default value for this method. Is there way to find default value in any method which i would like to override? In source code or somewhere? I need override more function and i would like to find any default value. Thanks
class myStatement extends PDOStatement
{
public function bindColumn ($column, &$param, $type = ?, $maxlen = ?, $driverdata = ?)
{
}
}

The only reason why I'm posting this as answers is that I can't post it as a comment.
/**
* (PHP 5 >= 5.1.0, PECL pdo >= 0.1.0)<br/>
* Bind a column to a PHP variable
* #link http://php.net/manual/en/pdostatement.bindcolumn.php
* #param mixed $column <p>
* Number of the column (1-indexed) or name of the column in the result set.
* If using the column name, be aware that the name should match the
* case of the column, as returned by the driver.
* </p>
* #param mixed $param <p>
* Name of the PHP variable to which the column will be bound.
* </p>
* #param int $type [optional] <p>
* Data type of the parameter, specified by the PDO::PARAM_* constants.
* </p>
* #param int $maxlen [optional] <p>
* A hint for pre-allocation.
* </p>
* #param mixed $driverdata [optional] <p>
* Optional parameter(s) for the driver.
* </p>
* #return bool <b>TRUE</b> on success or <b>FALSE</b> on failure.
*/
public function bindColumn ($column, &$param, $type = null, $maxlen = null, $driverdata = null) {}
Get yourself a decent IDE man, it works wonders.

The signature of this method is:
public function bindColumn ($column, &$param, $type = null, $maxlen = null, $driverdata = null) {}
You can use modern IDE like PHPStorm for example to find the signature of any method and other useful information

Related

Symfony 5 / Doctrine: Sorting entity collection by creation DateTime

I am developing a project using Symfony 5. One of my use-cases involves reading a collection from the Database, with the items sorted by creation order, descending (newest first). I am using the "Timestampable" extension from "stof/doctrine-extensions-bundle" to save the createdAt and updatedAt timestamps in my entity.
According to Doctrine documentation, I can sort items ussing the Repository methods:
$sortedEntities = $repository->findBy(array('createdAt' => 'DESC'));
This is the attribute in question:
/**
* #var \DateTime $createdAt
*
* #Gedmo\Timestampable(on="create")
* #ORM\Column(type="datetime")
*/
private $createdAt;
However, using 'ASC' or 'DESC' seems to have no impact on the ordering of the list.
You are not reading the documentation correctly. The orderBy is the second argument, not the first.
The example given in the docs is
$tenUsers = $em->getRepository('MyProject\Domain\User')->findBy(array('age' => 20), array('name' => 'ASC'), 10, 0);
Here, you can see the orderBy (name, ASC) is the second arg. The first arg is a where arg - in this case, WHERE age = 20.
Here is the full signature from Doctrine\Persistence\ObjectRepository
/**
* Finds objects by a set of criteria.
*
* Optionally sorting and limiting details can be passed. An implementation may throw
* an UnexpectedValueException if certain values of the sorting or limiting details are
* not supported.
*
* #param array<string, mixed> $criteria
* #param string[]|null $orderBy
* #param int|null $limit
* #param int|null $offset
* #psalm-param array<string, 'asc'|'desc'|'ASC'|'DESC'> $orderBy
*
* #return object[] The objects.
* #psalm-return T[]
*
* #throws UnexpectedValueException
*/
public function findBy(array $criteria, ?array $orderBy = null, $limit = null, $offset = null);
I hope that clarifies it for you. :-)
[EDIT] In response to your comment, you cannot use true as a value for the first argument. Look at the signature I posted. The first argument is #param array<string, mixed>, so it needs an array. Try this then:
sortedEntities = $repository->findBy(array(), array('createdAt' => 'DESC'));

PhpDocs: Link to another method in "#deprecated" tag's description?

Is it possible to link to another method/class/property/etc. inside my project inline inside the #deprecated tag? Like this:
/**
* Method description
* #deprecated 1.0 Reason for deprecation, use {#link newMethod()} instead!
* #param string $str
* #param string|null $str2
* #return bool
*/
public function method($str, $str2) {
// TODO: Code...
}
...
?
According to PHPdoc.org, you could use the #see tag for that.
/**
* #see http://example.com/my/bar Documentation of Foo.
* #see MyClass::$items For the property whose items are counted.
* #see MyClass::setItems() To set the items for this collection.
*
* #return integer Indicates the number of items.
*/
function count()
{
<...>
}
Also, PHPdoc.org recommends to use #see in case of a #deprecated method:
It is RECOMMENDED (but not required) to provide an additional description stating why the associated element is deprecated. If it is superceded by another method it is RECOMMENDED to add a #see tag in the same PHPDoc pointing to the new element.
But #see is not always required, for example "Link to another method in #param tag's description?"

Using DQL functions inside Doctrine 2 ORDER BY

I'm doing a project in Symfony 2.3 with Doctrine 2.4 using MySQL database.
I have an Entity of FieldValue (simplified):
class FieldValue
{
/**
* The ID
*
* #var integer
*/
protected $fieldValueId;
/**
* Id of associated Field entity
*
* #var integer
*/
protected $fieldId;
/**
* Id of associated user
*
* #var integer
*/
protected $userId;
/**
* The value for the Field that user provided
*
* #var string
*/
protected $userValue;
/**
* #var \MyProjectBundle\Entity\Field
*/
protected $field;
/**
* #var \MyProjectBundle\Entity\User
*/
protected $user;
The problem I have is the fact that $userValue, while it's LONGTEXT in my database, can represent either actual text value , date or number, depending in the type of the Field.
The Field can be dynamically added. After adding a one to any of the users every other user can also fill it's own value for that Field.
While querying the database I use orderBy to sort on a certain column, which also can be one of those Fields. In that case I need to sort on $userValue. This is problematic when I need to have number fields sorted as numbers, and not as strings ('123' is less than '9' in that case...).
The solution for it (I thought) is to CAST the $sort, so I would get SQL like:
ORDER BY CAST(age AS SIGNED INTEGER) ASC
Since Doctrine does not have a built-in DQL function for that, I took the liberty of adding that to my project as INT DQL function (thanks to Jasper N. Brouwer):
class CastAsInteger extends FunctionNode
{
public $stringPrimary;
public function getSql(SqlWalker $sqlWalker)
{
return 'CAST(' . $this->stringPrimary->dispatch($sqlWalker) . ' AS SIGNED INTEGER)';
}
public function parse(Parser $parser)
{
$parser->match(Lexer::T_IDENTIFIER);
$parser->match(Lexer::T_OPEN_PARENTHESIS);
$this->stringPrimary = $parser->StringPrimary();
$parser->match(Lexer::T_CLOSE_PARENTHESIS);
}
}
So happy with myself finding an easy solution I did that:
$sort = "INT(".$sort.")";
$queryBuilder->orderBy($sort, $dir);
which produced expected DQL:
ORDER BY INT(age) ASC
But also produced an exception:
An exception has been thrown during the rendering of a template ("[Syntax Error] line 0, col 12272: Error: Expected end of string, got '('") in MyProject...
So I've tried to find out what is going on and got into this in Doctrine\ORM\Query\Parser.php:
/**
* OrderByItem ::= (
* SimpleArithmeticExpression | SingleValuedPathExpression |
* ScalarExpression | ResultVariable
* ) ["ASC" | "DESC"]
*
* #return \Doctrine\ORM\Query\AST\OrderByItem
*/
public function OrderByItem()
{
...
}
Does that mean that there is no possibility to use DQL functions inside ORDER BY?
And if this is the case - is there any other way to achieve this?
UPDATE
I actually already have INT used in my select query, inside CASE WHEN:
if ($field->getFieldType() == 'number') {
$valueThen = "INT(".$valueThen.")";
}
$newFieldAlias = array("
(CASE
WHEN ...
THEN ".$valueThen."
ELSE ...
END
) as ".$field->getFieldKey());
Later on the $newFieldAlias is being added to the query.
Doesn't change anything...
UPDATE 2
Even when I add an extra select to the query, which will result in this DQL:
SELECT age, INT(age) as int_age
and then sort like that:
ORDER BY int_age ASC
I still don't het the correct result.
I've checked var_dump from $query->getResult(), and this is what I got:
'age' => string '57' (length=2)
'int_age' => string '57' (length=2)
Like CAST does not matter. I'm clueless...
Doctrine DQL does not accept functions as sort criteria but it does accept a "result variable". It means that you can do the following:
$q = $this->createQueryBuilder('e')
->addSelect('INT(age) as HIDDEN int_age')
->orderBy('int_age');
Doctrine 2 does not support INT by default, but you can use age+0.
$q = $this->createQueryBuilder('e')
->addSelect('age+0 as HIDDEN int_age')
->orderBy('int_age');
It is problem in your parser.php file. I have similar kind of issue and I solve this issue to replace below code in my parser file.
/**
* OrderByClause ::= "ORDER" "BY" OrderByItem {"," OrderByItem}*
*
* #return \Doctrine\ORM\Query\AST\OrderByClause
*/
public function OrderByClause()
{
$this->match(Lexer::T_ORDER);
$this->match(Lexer::T_BY);
$orderByItems = array();
$orderByItems[] = $this->OrderByItem();
while ($this->lexer->isNextToken(Lexer::T_COMMA)) {
$this->match(Lexer::T_COMMA);
$orderByItems[] = $this->OrderByItem();
}
return new AST\OrderByClause($orderByItems);
}
Just use this:
->orderBy('u.age + 0', 'ASC');

Auto-completion for Zend Form Elements

When creating form elements with Zend (using Zend Studio for Eclipse), I'd like some auto completion or hints. Here's what I'm thinking. I'm sure these exist, but I don't know how to get them.
I type createElement and auto-completes gives me the signature createElement($type, $name). Great, I select it.
but when I try to set the $type I don't get any hints like DateTextBox or ValidationTextBox. Being new, I see how this can be useful. What do you do to remember all the options?
for the array of attributes like require, invalidMessage, I'd like to get a list of those to choose from, and/or auto-complete when I start typing one.
// Date field
$date = $this->createElement('DateTextBox', 'date',
array('require' => 'true', 'invalidMessage' => 'Invalid date format')
);
$date->setLabel('date')->setRequired(true);
You have few options to help yourself, without waiting for any plugin:
learn it and remember ;)
extend your phpDoc blocks with all available options:
Example (to be honest I don't know if Eclipse supports html in phpDoc or even any text after variable name in #param, but it works fine in Netbeans):
/**
* [...]
* #param string $type Can be: <ul><li>DateTextBox</li><li>ValidationTextBox</li></ul>
* #param string $name Whatever
* #param array|Zend_Config $options Array with following keys: <ul><li>require</li><li>invalidMessage</li></ul>
* #return Zend_Form_Element
*/
public function createElement($type, $name, $options = null)
extend Zend class and create your own methods to simplify your work
Example:
class My_Zend_Form_Element extends Zend_Form_Element
{
public function createDateTextBox($name, $options = null)
{
return $this->createElement('DateTextBox', $name, $options);
}
}
declare some well named constants and provide some hint in phpDoc
Example: (type ZFE_OPTIONS and IDE should show hint with some constants to use as array keys)
/**
* Can be true or false
*/
define('ZFE_OPTIONS_REQUIRE','require');
create your own helper classes with methods to produce valid options array
Example:
class ZFE_Options
{
protected $opts = array();
/**
* #param bool $req
* #return ZFE_Options
*/
public function setRequired($req){
$this->opts['require'] = (bool)$req;
return $this;
}
/**
* #param string $txt
* #return ZFE_Options
*/
public function setInvalidMessage($txt){
$this->opts['invalidMessage'] = (string)$txt;
return $this;
}
/**
* #return array
*/
public function toArray(){
return $this->opts;
}
}
$zfe_options = new ZFE_Options();
$opts = $zfe_options
->setRequired(true)
->setInvalidMessage('Please provide valid email address')
->toArray();
That's not possible. It's not how autocompletion works. The hints you get are taken directly from ZF's code documentation. Nothing more, nothing less. Everything you see as hints is taken directly from the DocBlock and method signature, e.g.
/**
* Create an element
*
* Acts as a factory for creating elements. Elements created with this
* method will not be attached to the form, but will contain element
* settings as specified in the form object (including plugin loader
* prefix paths, default decorators, etc.).
*
* #param string $type
* #param string $name
* #param array|Zend_Config $options
* #return Zend_Form_Element
*/
public function createElement($type, $name, $options = null)
Eclipse can tell you to insert a string or an array and it will know that the method returns a Zend_Form_Element, but it cannot tell you what these strings should be.
The only place where I know something like what you describe exists is for CSS files. For some reason, when I type in display: it will give me an autocomplete box with possible values for this declaration. If you want more sophisticated autocomplete like this, consider filing this as a feature request to Zend.

How to document an accessor/mutator method in phpDoc/javaDoc?

Given a function which behaves as either a mutator or accessor depending on the arguments passed to it, like this:
// in PHP, you can pass any number of arguments to a function...
function cache($cacheName) {
$arguments = func_get_args();
if (count($arguments) >= 2) { // two arguments passed. MUTATOR.
$value = $arguments[1]; // use the second as the value
$this->cache[$cacheName] = $value; // *change* the stored value
} else { // 1 argument passed, ACCESSOR
return $this->cache[$cacheName]; // *get* the stored value
}
}
cache('foo', 'bar'); // nothing returned
cache('foo') // 'bar' returned
How do you document this in PHPDoc or a similar automated documentation creator? I had originally just written it like this:
/**
* Blah blah blah, you can use this as both a mutator and an accessor:
* As an accessor:
* #param $cacheName name of the variable to GET
* #return string the value...
*
* As a mutator:
* #param $cacheName name of the variable to SET
* #param $value the value to set
* #return void
*/
However, when this is run through phpDoc, it complains because there are 2 return tags, and the first #param $cacheName description is overwritten by the second.
Is there a way around this?
as you found out, you cannot document 2 different signatures of a single function. what you can do, however - if you use phpDocumentor -, is to document optional function parameters and multiple possible return types:
/**
* Blah blah blah, you can use this as both an accessor and a mutator, e.g.
* <code>cache('name') // get cache value</code>
* and
* <code>cache('name', 'value') // set new cache value</code>.
*
* #param string $cacheName name of the variable to GET|SET
* #param string $value optional new value
*
* #return string|void value of $cacheName or, in case of mutator, void
*/
for clarity, i would also include the usage example.

Categories