I have a problem with prepare function ==> Call to a member function prepare() on null
i have tow pages classo.php and index.php
classo.php :
<?php
class classo
{
function connection(){
$db=new pdo ('mysql:host=localhost;dbname=pronostic','root','');
$db->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_WARNING);
}
function insererDonne($pseudo,$password)
{
global $db;
classo::connection();
$donne=array(
'user' =>$pseudo,
'pass' =>$password
);
$req="INSERT INTO users (user,pass) VALUES (:user,:pass)";
$sql=$db->prepare($req);
$sql->execute($donne);
}
}
?>
index.php:
<?php
require('classo.php');
$data=new classo();
$data->insererDonne('dsds','tosdsta');
?>
Do you have an idea as to how I can resolve this? This is the first time I've received this error from PHP and I'm kind of new coding in PHP with objects & classes. Could someone help me fix this problem please?
There are 2 big issues in your code:
Variable visibility
Static call
In detail:
In oop you should forget about global variables. They are against the principle of encapsulation. Moreover, you do not even have any global variable in your code, so global $db; line is meaningless. Declare a private $db variable on class level (property) initialise it in the connection() method and access it in the insert method.
You are calling the connection method as classo::connection();. However, you would need to declare connection method as static. Either declare your connection method as static (but then change $db into static as well), or call it as a regular method using $this.
Related
In PHP I have:
protected function registerTwigFunctions()
{
return [
'count_VKcomments' => 'countVKCommentsFunction'
];
}
public function countVKCommentsFunction($context, $pdo) {
$url = $context['url'];
$sql = "SELECT id, COUNT(*) FROM level_1 WHERE url = ?";
$count = $pdo->prepare($sql)->execute([$url])->fetchColumn();
return $count;
}
In Twig I have:
{% set url = global.request.uri %}
{{ count_VKcomments({ 'url': url }) }
But it only works if I remove the $pdo argument from countVKCommentsFunction, otherwise some temporary file complains about too few arguments being passed from Twig. But I need to include that $pdo argument just to avoid duplicating connection to the database, which is already defined as $pdo in another function. At the same time, I don't understand how to properly call countVKCommentsFunction provided that it needs $pdo as an argument.
From perspective of Twig your function should only accept/care about what template practically needs to pass to it.
From perspective of PHP implementation your function needs access to state of your application (your database connection in this case).
The solution here is to decouple the two tasks:
Make and instantiate object that has access to the necessary state.
Use the object's method as callback for Twig function.
That way template data comes through arguments and state data comes through implementation.
I ended up creating a separate function that defines $pdo:
private function pdo() {
$core = Core::getInstance();
$pdo = $core->dbh;
return $pdo;
}
Then in every function that needs to use this variable I added $pdo = $this->pdo();
Another approach would be to declare the variable as a class member, but I ended up doing it like I described.
This question already has answers here:
Reference - What does this error mean in PHP?
(38 answers)
Closed 8 years ago.
So I'm refactoring my code to implement more OOP. I set up a class to hold page attributes.
class PageAtrributes
{
private $db_connection;
private $page_title;
public function __construct($db_connection)
{
$this->db_connection = $db_connection;
$this->page_title = '';
}
public function get_page_title()
{
return $this->page_title;
}
public function set_page_title($page_title)
{
$this->page_title = $page_title;
}
}
Later on I call the set_page_title() function like so
function page_properties($objPortal) {
$objPage->set_page_title($myrow['title']);
}
When I do I receive the error message:
Call to a member function set_page_title() on a non-object
So what am I missing?
It means that $objPage is not an instance of an object. Can we see the code you used to initialize the variable?
As you expect a specific object type, you can also make use of PHPs type-hinting featureDocs to get the error when your logic is violated:
function page_properties(PageAtrributes $objPortal) {
...
$objPage->set_page_title($myrow['title']);
}
This function will only accept PageAtrributes for the first parameter.
There's an easy way to produce this error:
$joe = null;
$joe->anything();
Will render the error:
Fatal error: Call to a member function anything() on a non-object in /Applications/XAMPP/xamppfiles/htdocs/casMail/dao/server.php on line 23
It would be a lot better if PHP would just say,
Fatal error: Call from Joe is not defined because (a) joe is null or (b) joe does not define anything() in on line <##>.
Usually you have build your class so that $joe is not defined in the constructor or
Either $objPage is not an instance variable OR your are overwriting $objPage with something that is not an instance of class PageAttributes.
It could also mean that when you initialized your object, you may have re-used the object name in another part of your code. Therefore changing it's aspect from an object to a standard variable.
IE
$game = new game;
$game->doGameStuff($gameReturn);
foreach($gameArray as $game)
{
$game['STUFF']; // No longer an object and is now a standard variable pointer for $game.
}
$game->doGameStuff($gameReturn); // Wont work because $game is declared as a standard variable. You need to be careful when using common variable names and were they are declared in your code.
function page_properties($objPortal) {
$objPage->set_page_title($myrow['title']);
}
looks like different names of variables $objPortal vs $objPage
I recommend the accepted answer above. If you are in a pinch, however, you could declare the object as a global within the page_properties function.
$objPage = new PageAtrributes;
function page_properties() {
global $objPage;
$objPage->set_page_title($myrow['title']);
}
I realized that I wasn't passing $objPage into page_properties(). It works fine now.
you can use 'use' in function like bellow example
function page_properties($objPortal) use($objPage){
$objPage->set_page_title($myrow['title']);
}
This is my php page persona.php:
<?php
class persona {
private $name;
public function __construct($n){
$this->name=$n;
}
public function getName(){
return $this->name;
}
public function changeName($utente1,$utente2){
$temp=$utente1->name;
$utente1->name=$utente2->name;
$utente2->name=$temp;
}
}
?>
The class persona is simple and just shows the constructor and a function that change two users name if called.
This is index.php:
<?php
require_once "persona.php" ;
$utente1 = new persona("Marcello");
print "First user: <b>". $utente1->getName()."</b><br><br>";
$utente2 = new persona("Sofia");
print "Second user: <b>". $utente2->getName()."</b><br>";
changename($utente1,$utente2);
print " Test after name changes: first user". $utente1->getName()."</b> second user". $utente2->getName();
?>
What I do not understand is how to call the changeName function from here.
I can understand where the confusion arises from...I think you are unsure if you should call changename on $utente1 or $utente2. Technically you can call it from either objects because they are both instances of Persona
But for clarity (and sanity), I would recommend converting the changeName function to a static function in its declaration:
public static function changeName($utente1,$utente2){
and then in your index.php you can call it as:
Persona::changename($utente1,$utente2);
From an architecture stamp point, this will help provide a better sense that the function is tied to the class of Persona, and objects can change swap names using that class function, as opposed to making it an instance function and then having any object execute it.
In your particular case you can call it as:
$utente1->changename($utente1,$utente2);
or
$utente2->changename($utente1,$utente2);
It doesn't matter which. As the method itself doesn't work with the classes properties (but only with the method parameters), you can call it from any object that exist.
But better (best practice, and better by design) is to develop a static method, as Raidenace already said, and call it like:
Persona::changename($utente1,$utente2);
I met a problem when Call to a member function combinestring() on a non-object.
**Index.php**
inlcude("string.php");
calldata('usa');
**string.php**
$a=new a();
funciton calldata($val){
$st1="select a from table 1 where country=".$a->combinestring($val);
return $st1;
}
**Class A**
function combinestring($abc){
Return "'".$abc."'";
}
Unknow $a->combinestring($val);
How to solve this problem.
Best Regards
You're getting error
Call to a member function combinestring() on a non-object
because you are calling a member function on the variable that is not an object. That means $a is not an object.
In string.php , you cannot use $a inside function definition because variable has local scope. You cannot access that object instance like that. You can however do this by using global variable.
Your string.php file should be like this:
$a=new a();
funciton calldata($val){
global $a;
$st1="select a from table 1 where country=".$a->combinestring($val);
return $st1;
}
Head to this link for more information on variable scope: http://php.net/manual/en/language.variables.scope.php
Use PDO.
funciton calldata($val){
$st1="select a from table 1 where country = ?";
$pdo = new PDO('host', 'user', 'pass');
$result = $pdo->prepare($st1)->execute($val);
return $result;
}
This is a lot different from what you are doing, but your a class does not escape the input to the query and that's bad.
I have declared a static method in class category
public static function getPrefixFromSubCategoyId($subCategoryId) {
$prefix = $this->fetch(array('table' => 'subCategories', 'id' => $subCategoryId));
return $prefix[0]['prefix'];
}
i am sure that i am using correct piece of code because when i use the same code outside the class scope with following code it works properly
$category = new Category($dbh);
$subCategoryId = 6;
$prefix = $category->fetch(array('table' => 'subCategories', 'id' => $subCategoryId));
echo $prefix[0]['prefix'];
but when i initialize the static method with following syntax.
$prefix = Category::getPrefixFromSubCategoyId(4);
it gives me following error.
Fatal error: Using $this when not in object context
am i missing something? or am i declaring it the wrong way?
thank you..
static methods are class members and aren't bound to an object. This means, that $this simply doesn't exists. You cannot use it in static methods. If fetch() is static too, call it static
self::fetch(/* arguments */);
If not either getPrefixFromSubCategoyId() should not be static too, fetch() should be static (see example above), or you need an object
$tmp = new self;
$tmp->fetch(/* arguments */);
$this is a reference to the current object. It is not the reference to the class. Since you are using it statically you have no object. You would have to make a static call in there as well.
$this is used to get instance variables or methods (simple members and basically the current object if you have one defining with new) but when you want to reach the static variables you should use $self::some_varible and :: is scope resolution operator.
You must declare your methods or variables static if you do want to use them under a static function.