Avatar of Alex Lord
Alex Lord
 asked on

Setting up gmail class

  class GmailService {

            public $service;
            private $client;
            private $gmToken;
            private $refreshToken;

            public function __construct($service)
            {

               //using pdo to get tokans for the foreach below//
    
                foreach($result as $getTOKEN){
                    $gmToken = $getTOKEN['TOKEN'];
                    $gmReToken = $getTOKEN['TOKEN_REFRESH'];
                }

               
                $client = $this->getGmClient($gmToken, $gmReToken);
                $service = new Google_Service_Gmail($client);
           
            }

Open in new window



am i setting up this class correctly ? im setting up a gmail class so when the page loads this script is called and im trying to setup the variables on the contruct, is this correct?

im getting the tokan if it exists and setting up the gmail service.
PHP* classesGmail

Avatar of undefined
Last Comment
Chris Stanyon

8/22/2022 - Mon
Chris Stanyon

Looks a little odd. The ctor is used to pass information into the class when it is instantiated. Looking at your code, you seem to be implying that $service is needed to set up the class, but you don't ever use this $service. What you are doing is creating a new $service using the $gmToken and $gmReToken. That info looks like it is being retrieved from the DB. You probably need to pass some info into the class that will allow you to query the DB.

A few other things of note.

In your ctor, you seem to be looping over something (assuming a DB result). Each time over the loop and you will overwrite the values of $gmToken and $gmReToken, so by the time you get to creating the new service, you will only be using the last values. If your DB only ever returns 1 record (which I'm guessing it should), then you don't need to loop over the results - just grab the results. It would also make sense here to grab the result as an Object rather than an Array (you are working with Objects after all).

Secondly, inside a class, whenever you're setting or getting an internal class field ($service, $client, $gmToken, $gmReToken etc.), you must refer to them with $this->.

Have a look at this:

class GmailService {

    public $service;

    private $client;
    private $gmToken;
    private $refreshToken;
    private $db;

    public function __construct(int $id)
    {
        // set up your PDO connection here and store it in $this->db
        $this->db = new PDO(...);

        $this->db->prepare("SELECT token, token_refresh FROM yourTable WHERE id = ?");

        $stmt = $this->db->execute($id);
        $user = $stmt->fetch();

        $this->gmToken = $user->token;
        $this->gmReToken = $user->token_refresh;
        
        $this->client = $this->getGmClient($this->gmToken, $this->gmReToken);
        $this->service = new Google_Service_Gmail($this->client);
    }

Open in new window

It'll need some work doing on it (definitely error/exception handling), but it should hopefully give you a better idea of how classes work.
ASKER CERTIFIED SOLUTION
Julian Hansen

THIS SOLUTION ONLY AVAILABLE TO MEMBERS.
View this solution by signing up for a free trial.
Members can start a 7-Day free trial and enjoy unlimited access to the platform.
See Pricing Options
Start Free Trial
GET A PERSONALIZED SOLUTION
Ask your own question & get feedback from real experts
Find out why thousands trust the EE community with their toughest problems.
Chris Stanyon

Totally agree with Julian on this - Dependency Injection is the way to go regarding the DB. The idea behind dependency injection is to de-couple your class from the dependencies it needs. As I coded, your GMail class would be tightly coupled to a specific connection to the DB. By injecting the connection, you remove this coupling, allowing you better re-use of your class (you can pass whatever PDO connection in). It's a fundamental principle of OOP.

Regarding the $stmt->fetch(PDO::FETCH_OBJ), that makes perfect sense. I tend to always set this up as the default in the PDO ctor.

$options  = [
    PDO::ATTR_EMULATE_PREPARES   => false,
    PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_OBJ,
];

$db = new PDO($dsn, $username, $password, $options);

Open in new window


This way, I'm always fetching objects by default, and I can then override if I ever need an array (yuck!). In this case it's probably right to put it in the class in case you forget to set the default in the injected PDO :)
Julian Hansen

I tend to always set this up as the default in the PDO ctor.
+1
I suspected you might be but as you did not include your PDO connection code - most people leave that out - and if they do fetch() defaults to both indexed and Assoc array - which would then be confusing.

For EE I prefer to be explicit - so if the constructor step is missed (Setting the mode) the rest of the code still works.
I started with Experts Exchange in 2004 and it's been a mainstay of my professional computing life since. It helped me launch a career as a programmer / Oracle data analyst
William Peck
Alex Lord

ASKER
Thank you both for the tips and points, i will deff need to re-read but it has given me a far better scope on doing this.

thanks for the new learning
Julian Hansen

You are welcome.
Chris Stanyon

No worries :)
⚡ FREE TRIAL OFFER
Try out a week of full access for free.
Find out why thousands trust the EE community with their toughest problems.