Jump to content

Call to undefined method in included file


richarddunnebsc

Recommended Posts

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?

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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 by mac_gyver
  • Like 1
Link to comment
Share on other sites

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?

 

Link to comment
Share on other sites

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';

Link to comment
Share on other sites

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;

 

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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 by richarddunnebsc
Link to comment
Share on other sites

  • 2 weeks later...

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 

 

Link to comment
Share on other sites

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.  

Link to comment
Share on other sites

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?

Link to comment
Share on other sites

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.

 

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.

 

 

 

 

 

Link to comment
Share on other sites

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?

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.