mysqli misses some methods in new phpstorm eap 6
Hello,
since now this worked fine.
When $mysqlStatement was of type mysqli, i could use $mysqlStatement->execute() or $mysqlStatement->bind_param(.....) and so on, no errors.
Since the newest EAP 6 of phpstorm, all methods are marked as "Method 'execute' not found in class....".
Did I do a mistake, or am I missing something, or is that a new bug that hasn´t been there in the last version?
Thank you a lot.
Please sign in to leave a comment.
Hi Adrian,
Can you please provide some small code example so I can copy-paste to confirm the issue?
Quite possibly that there is an issue with a stub for specific method (which has incorrect @return parameter).
In any case: please try "File | Invalidate Caches..." in case you have not tried it yet.
Hi Andrji,
the following (parts) of code worked before without any errors (I left some things to make it smaller and cleaner for demonstration purposes). The errors appear since the newsest phpStorm EAP 6 version 126.92.
if (($mysqlStatement = $initVars->myDBC->sqliMain->prepare('INSERT INTO members_friendinvitations (member_invitor_uid, member_invited_uid, invitation_code1, invitation_code2, invitation_datetime) VALUES (?, ?, ?, ?, FROM_UNIXTIME(?))')) !== false) {
$mysqlStatement->bind_param('iissi', $initVars->memberUid, $initVars->athleteUid, $invitationCode1, $invitationCode2, time());
$mysqlStatement->execute();
$mysqlStatement->close();
$dbError = false;
} else {
$myagTools->sqliErrorHandler($initVars->myDBC->sqliMain, __METHOD__, __LINE__);
$dbError = true;
}
$initVars is an instance of a "agInit" class; it contains some of my most important variables for my project. I know that it is not best practice to call public variables of that class (e.g. myDBC, sqliMain), but it worked fine and was easy to code - and - it made no errors in phpStorm.
Right now I have to set /** @var mysqli_stmt $mysqlStatement */ in front of the if.... then the errors under 'bind_param', 'execute', 'close' vanish. okay.
But still I have the error under prepare: method 'prepare' not found in class. But sqliMain is of type mysqli, and it is a public member of myDBC....
That worked before fine.
If I use this:
$myDBC->sqliMain->prepare
instead of
$initVars->myDBC->sqliMain->prepare
everything works fine.... hmmm.... it seems to me that phpStorm does not recognize the type of sqliMain if it is accessed through another class....
Thanks a lot.
Nachricht geändert durch Adrian Grund
Hi Adrian,
Since I do not have all the classes/variables involved in your example, I have tried to simplify it like below and it works just fine (no warnings in this regard)
I assume that "File | Invalidate Caches" did not helped you then (...
My only suggestion here then ... is to invoke Quick Documentation (Ctrl+Q) for each chain element and see what PhpStorm thinks about it (is return type is correct etc etc): $initVars->myDBC->sqliMain->prepare
Can you please provide a simplified version of these classes (only properties/methods that are used in this problematic example -- must contain any PHPDocs if you have any ect)
Thank you,
here is the relevant code:
class agInit
{
public $myDBC = null;
/**
* Constructor
*
* @param string $brd brd
*
* @return void
* @version SVN: $Id: agInit.class.php 342 2013-02-02 23:35:06Z svnadrian $
*/
function agInit($brd)
{
include_once 'database/agDBConnectionsModel.php';
...
...
$this->myDBC = new agDBConnections(...some variables for initiating db connection....);
}
class agDBConnections
{
public $sqliMain = null;
/**
* Constructor
*
* @param string $definitionsDbSERVER the server name
* and some more.......
* @return void
* @version SVN: $Id: agDBConnections.class.php 330 2012-09-25 06:50:19Z svnadrian $
*/
public function agDBConnections(...some variables for initiiating db connection)
{
$this->sqliMain = new mysqli($agDbSERVER, $agDbUSER, $agDbPASS, $agDbDATABASE);
$this->sqliMain->set_charset('utf8');
}
}
in index.php:
$brd = '/';
$initVars = new agInit($brd);
$initVars->myDBC->sqliMain->prepare(.....)
That worked before.
When I do like in your example: $myDBC = new AGDBConnections(....)
and then: $myDBC->sqliMain->prepare(....) everything works fine.
So in my opinion the "transportation" of the type mysqli or something like that through the class agInit does not work anymore....
(sorry my english is so bad so I cannot dexribe the error better).
Thank you a lot! Adrian.
Here is the code after "cleaning up" (removing unrelated stuff). I have also added PHPDoc comments for $myDBC and $sqliMain fields:
Despite the fact that I have manually provided correct type for those fields, PhpStorm still adds |null (default value/type). This means that $myDBC in eyes of PhpStorm looks like /** @var agDBConnections|null */. Somehow, when declaration and usage in different files, PhpStorm looses / ignores one of the types.
Solution -- get rid of default null value, so PhpStorm has only ONE class to check against (null as a type has no (and cannot have) methods at all):
I'm pretty sure that I have seen more than one ticket for this, but I still would suggest to file new one to the Issue Tracker -- hopefully more tickets will tell devs that this incorrect behaviour needs to be fixed once and for all.
Andriy,
thanks a lot. You are the hero of the day and saved my time!
It works.
But there´s still one question. I only sent you a part of that class; I have more public variables that capsule other classes, and they work fine, though I init this variables at the beginning WITH null.... hmmm... but I can live with that.
Thanks a lot!
May I ask you one last question?
For database connections to mysql databases... what do you prefer? Do you save the database connection in a variable at the beginning of the script and pass this database connection variable as a parameter to the functions that need database access? Or do you use a static database class / singleton pattern where you can use that connection "global" in all functions?
I think the easier way is second, the "good practice" the first? What do you mean? Thank you a lot.
No idea. As we can clearly see from this particular example .. PhpStorm has some issues here.
It all depends on your application:
If you plan to use unit testing, then Singleton is rather bad idea (you can google for opinions, e.g. http://googletesting.blogspot.co.uk/2008/11/clean-code-talks-global-state-and.html ; http://googletesting.blogspot.co.uk/2008/08/by-miko-hevery-so-you-join-new-project.html ). The same is if your app is modular -- Dependency Injections / Service Locator / Registry are better here. With Dependency Injection approach you can use fake DB connection to test your around-db code without making actual DB operations -- e.g. to test how it will behave in specific critical situations (e.g. missing field; no db connection; db with such name is not found etc).
Generally speaking, I would:
There are advantages and disadvantages in each approach -- you need to choose the one that will suit you / required task the best. Using lots of classes / executing additional abstraction calls will make your code slower (compared to straight-forward and not-so-flexible approach) and will require more server resources. On another hand -- such code easier to modify/extend/test etc.
Andriy,
thanks a lot for your long, detailed and very clear answer. Seems that I see clearer now. More and more I learn, that there is no black and white in coding... it depends on the circumstances.
Best wishes, Adrian.