richarddunnebsc Posted November 20, 2021 Share Posted November 20, 2021 I'm using wamp. I have Logic.php and Data.php in the same folder. In Logic.php I have include_once('Data.php'); and a Logic class containing public function EmailVerify() { try { $registered = $this->Email(); if($registered) { echo "Registered"; } } catch (PDOException $e) { echo 'Error: ' . $e->getMessage(); } } I am getting call to undefined function Logic::Email(), Email() is a method in Data.php What am I doing wrong? Quote Link to comment Share on other sites More sharing options...
ginerjm Posted November 20, 2021 Share Posted November 20, 2021 This is a guess but when you reference "Logic::Email()" aren't you saying that Email() is a method of that class? It is simply a function in a different module which doesn't have to be referenced in that fashion. Try simply calling the function. PS - try using require instead of include. That way you get an error if it isn't found. PS#2 - you don't need the parens on the include or require statement. Quote Link to comment Share on other sites More sharing options...
richarddunnebsc Posted November 20, 2021 Author Share Posted November 20, 2021 Using require instead of include makes no difference. If I use this instead $registered = $data->Email(); I get Undefined variable: data. If by parens you mean parenthesis, if I leave them out, I get failed to open stream, no such file Dataphp. Quote Link to comment Share on other sites More sharing options...
ginerjm Posted November 20, 2021 Share Posted November 20, 2021 Why the use of $data-> You are attempting to call a stand-alone function that is not part of any class, correct? So just say "Email()". Quote Link to comment Share on other sites More sharing options...
richarddunnebsc Posted November 20, 2021 Author Share Posted November 20, 2021 I want to call the Data class method Email() in Data.php from Logic.php Quote Link to comment Share on other sites More sharing options...
mac_gyver Posted November 20, 2021 Share Posted November 20, 2021 (edited) the error about an undefined variable is the same problem at the start of your thread in a different help forum. php class methods have local variable scope. if the logic class is truly dependent on the data class, you would use dependency injection to make the instance of the data class available in the logic class. however, i doubt that is actually what you are trying to do. you need to post all the relevant code in order to get the best solution. based on the names you have given your classes, you have taken the data and processing for a task and surrounded each of them with class definitions. this is not OOP. OOP is not about doing a bunch of typing adding a bunch of defining and calling syntax, then adding $var-> or $this-> in front of everything in order to make it work. all this is doing is wasting time adding a layer to your code that adds no value to that you are doing. Edited November 20, 2021 by mac_gyver 1 Quote Link to comment Share on other sites More sharing options...
richarddunnebsc Posted November 20, 2021 Author Share Posted November 20, 2021 I'm not passing any data from Logic.php (Logic class) to Data.php (Data class) There is no dependency on Data.php by Logic.php, but I need to include Data.php in Logic.php in order to call methods in Data.php Data.php requires Config.php in order to access the database. As part of a user email verification, I want to access the necessary method(s) in the Data class from Logic.php. Hope that clarifies. As I have instantiated the Data class and Data.php is included in Logic.php, then shouldn't all the Data class methods by accessible to the Logic class using $this->FunctionName? If not, how else do I call methods in the Data class from Logic? Quote Link to comment Share on other sites More sharing options...
ginerjm Posted November 20, 2021 Share Posted November 20, 2021 Yes - you need to include the module into the other module to reference it of course. But you are not referring to it correctly which is what php is telling you. Your mention of $data is a problem since you haven't shown us where it is defined and instantiated with your small sample of code. The proper use is: include_once 'data.php'; or require_once 'data.php'; Quote Link to comment Share on other sites More sharing options...
richarddunnebsc Posted November 20, 2021 Author Share Posted November 20, 2021 I instantiated Data in both Data.php and Logic.php, but I still get Undefined variable: data in Logic require_once('Data.php'); error_reporting(E_ALL); ini_set('display_errors', '1'); $data = new Data; class Logic { public function EmailVerify() { try { $registered = $data->Email(); } catch (PDOException $e) { echo 'Error: ' . $e->getMessage(); } } } $logic = new Logic; Quote Link to comment Share on other sites More sharing options...
ginerjm Posted November 20, 2021 Share Posted November 20, 2021 $data is not defined in the scope of your Logic class. Pass it in as an argument: public function EmailVerify($data) Quote Link to comment Share on other sites More sharing options...
ginerjm Posted November 20, 2021 Share Posted November 20, 2021 Just noticed that you made a statement that wasn't true. I don't see where you instantiated $data in the logic class. You established it on the outer level of your script but you didn't pass it into the EmailVerify function call so that you could use it in there. Of course if there is more code that you could share with us you might want to show us so that we can help you. Quote Link to comment Share on other sites More sharing options...
richarddunnebsc Posted November 20, 2021 Author Share Posted November 20, 2021 I only only added the instantiation before my last post, it wasn't there before, as you observed. This code require_once('Data.php'); error_reporting(E_ALL); ini_set('display_errors', '1'); $data = new Data; class Logic { public function EmailVerify($data) { try { $registered = $data->Email(); } catch (PDOException $e) { echo 'Error: ' . $e->getMessage(); } } } $logic = new Logic; gives me Fatal error: Uncaught ArgumentCountError: Too few arguments to function Logic::EmailVerify(), 0 passed in Quote Link to comment Share on other sites More sharing options...
ginerjm Posted November 20, 2021 Share Posted November 20, 2021 (edited) If you would just show ALL of your code that pertains to this we could solve this. The message is saying you wrote EmailVerify(), and not EmailVerify($data) when you called the function. Edited November 20, 2021 by ginerjm Quote Link to comment Share on other sites More sharing options...
richarddunnebsc Posted November 20, 2021 Author Share Posted November 20, 2021 (edited) That's what it says, but as you can see, I have EmailVerify($data) and not EmailVerify() I was interpreting/reading the error message wrong. EmailVerify($data) has an argument in it, but it doesn't receive the argument from the calling method, hence 0 passed. I need to instantiate the Data class in the webpage, then pass it as an argument to the method in the Logic class, that makes sense, I hope. I have echo "yes"; in the Email() method in the Data class. It printed yes. Edited November 20, 2021 by richarddunnebsc Quote Link to comment Share on other sites More sharing options...
ginerjm Posted November 20, 2021 Share Posted November 20, 2021 You are already instantiating it in line 4. Then you are defining the class and method with the proper structure. It's where you then call EmailVerify that you are not passing the $data var. Quote Link to comment Share on other sites More sharing options...
richarddunnebsc Posted December 1, 2021 Author Share Posted December 1, 2021 This is my Db class in Config.php class Db extends PDO { private $host; private $dbName; private $user; private $pass; private $charset; public function Connect() { $this->host = "localhost"; $this->user = "root"; $this->pass = ""; $this->dbName = "dbName"; $this->charset = "utf8mb4"; try { $dsn = "mysql:host=".$this->host.";dbName=".$this->dbName.";charset=".$this->charset; $pdo = new PDO($dsn, $user, $pass, array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION)); return $pdo; } catch (PDOException $e) { echo 'Error: '.$e->getMessage(); } } } This is the PDO construct in my Data class in Data.php public function __construct() { $pdo = new PDO($this->dsn,$user,$pass, array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION)); } This line is giving Notice: Undefined property: Data::$dsn Notice: Undefined variable: user Notice: Undefined variable: pass Fatal error: Uncaught PDOException: invalid data source name Quote Link to comment Share on other sites More sharing options...
benanamen Posted December 1, 2021 Share Posted December 1, 2021 (edited) Why are you extending PDO? There is no reason for you to do that and you haven't "extended" anything. You already create a connection in Config.php. Why are you recreating it again in Data.php? Take a look at my "Clean PDO" example.https://github.com/benanamen/clean-pdo Edited December 1, 2021 by benanamen Quote Link to comment Share on other sites More sharing options...
richarddunnebsc Posted December 1, 2021 Author Share Posted December 1, 2021 The database connection has been sorted. My only other problem is calling a Data method from my Logic class. I have included Data.php in Logic.php Created a Data class object in Logic.php $data = new Data; then when I call a method in the Data class $registered = $data->MethodName(); I get Undefined variable: data I did the same thing calling a Logic class method from a webpage and had no issue. Quote Link to comment Share on other sites More sharing options...
richarddunnebsc Posted December 1, 2021 Author Share Posted December 1, 2021 Why is data undefined after $data = new Data; try { if(isset($data)) { $registered = $data->MethodName(); } else { echo "failed"; } } catch (PDOException $e) { echo 'Error: ' . $e->getMessage(); } This reason data is undefined is it's not creating a new Data class object It prints failed. Why is it not creating a new Data class object? Quote Link to comment Share on other sites More sharing options...
gizmola Posted December 1, 2021 Share Posted December 1, 2021 Each method or function should do one thing. You have lots of redundant/competing object instantiation going on. Think about what your classes do/are for. What purpose do you need. You also seem to have a basic misunderstanding of how class properties are available/used. 1st things 1st. One source file per class. Only the namespace statement and class code. The filename should match the classname. Once you get the hang of this things will start to come together quickly. 2 Things you can learn more about to upgrade your code/understanding of PHP Oop. Learn about PHP Namespaces. Start using them. Add composer to your project mix with an initial composer.json. PHP Namespaces: The basics of them PSR-4: How to name your classes and organize them in your source tree to match, so they can be autoloaded Using Composer for package management and autoloader generation Learn about Dependency Injection as a design pattern. This was suggested to you previously. A blog series on DI by Fabien Potencier, creator of the Symfony framework project To do PSR-0/4 compatible namespacing, you need an orgname. It doesn't matter what it is, but case matters. So for example, let's say you were writing things for Phpfreaks, and the team decided all code would use that as the organization name. Then the Top namespace is going to be Phpfreaks. In this example, Somename is a stand in for whatever you want to use for your code. Let's try a new Db class: <?php // Filename /src/Database/Db.php // In composer.json you will have a PSR-4 mapping for Somename mapping to your project src directory. You will place all your classes in directories beneath src, organized as you see fit. namespace Somename\Database\Db; class Db { private $host; private $dbName; private $user; private $pass; private $charset; private $pdo; public function __construct($host, $user, $pass, $dbName, $charset="utf8mb4") { $this->host = $host; $this->user = $user; $this->pass = $pass; $this->dbName = $dbName; $this->charset = $charset; $this->connect(); } protected function connect() { try { $dsn = "mysql:host=".$this->host.";dbName=".$this->dbName.";charset=".$this->charset; $this->pdo = new PDO($dsn, $user, $pass, array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION)); } catch (PDOException $e) { echo 'Error: '.$e->getMessage(); } } public function getConnection() { return $this->pdo; } } Before instantiating your Data class create a new instance of a DB class, passing in all the parameters to the constructor. In this example, charset is optional. The constructor will try to make the pdo connection. <?php use Somename\Database\Db; use Somename\Database\Data; $db = new Db('localhost', 'user', 'pw', 'database'); // Data class should store the $db parameter in a private variable in the constructor. $data = new Data($db); Then from within data you could be using $this->db for pdo connection related things. Quote Link to comment Share on other sites More sharing options...
maxxd Posted December 2, 2021 Share Posted December 2, 2021 5 hours ago, richarddunnebsc said: Why is data undefined after I agree with and you should heed both benananmen and gizmola's points. But for your specific question here looks - as ginerjm points to - like a question of scope. For instance, as you (I assume) learned fixing the database connection, you couldn't use $user or $pass variables within the __construct() method because you didn't pass those variables to the __construct() method. Every variable, method, and function (with some limited and typically ill-advised exceptions) has a scope outside of which it doesn't exist. So, look at where you define $data - is it in the same scope as where you use $data? Was it in the same function, or was it passed to the function that's trying to use it? Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.