Completed
Branch develop (981d8e)
by Oyebanji Jacob
04:12 queued 01:59
created

indexPDO.php (2 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
4
interface ModelInterface {
5
	/**
6
	 * Get all models from database.
7
	 *
8
	 * @return array
9
	 */
10
	function static getAll();
0 ignored issues
show
This code did not parse for me. Apparently, there is an error somewhere around this line:

Syntax error, unexpected T_STRING, expecting '('
Loading history...
11
12
	/**
13
	 * Find model with the specified id.
14
	 */
15
	function static find($id);
16
17
	/**
18
	 * Delete model with the specified id.
19
	 * 
20
	 */
21
	function static destroy($id);
22
}
23
24
abstract Model {
25
26
	/**
27
     * The connection name for the model.
28
     *
29
     * @var string
30
     */
31
    protected $connection;
32
33
34
}
35
36
class DatabaseConnectionFactory {
37
38
39
40
41
}
42
43
44
class Connection {
45
46
	/**
47
     * The current globally used instance.
48
     *
49
     * @var object
50
     */
51
    protected static $instance;
52
53
    private $host;
54
    private $user;
55
    private $pass;
56
    private $dbname;
57
 
58
    private $dbh;
59
    private $error;
60
 
61
    public function __construct(){
62
    	$config = parse_ini_file('config.ini');
63
        // Set DSN
64
        $dsn = 'mysql:host=' . $this->host . ';dbname=' . $this->dbname;
65
        // Set options
66
        $options = array(
67
            PDO::ATTR_PERSISTENT    => true,
68
            PDO::ATTR_ERRMODE       => PDO::ERRMODE_EXCEPTION
69
        );
70
        // Create a new PDO instanace
71
        try{
72
            $this->dbh = new PDO($dsn, $this->user, $this->pass, $options);
73
        }
74
        // Catch any errors
75
        catch(PDOException $e){
76
            $this->error = $e->getMessage();
77
        }
78
    }
79
}
80
81
82
try {
83
	 
84
	$dbh = new PDO('mysql:host=localhost;dbname=potatoORM', 'homestead', 'secret');
85
	foreach($dbh->query('SELECT * from test') as $row) {
86
	        print_r($row);
87
	    }
88
} catch (PDOException $e) {
89
    print "Error!: " . $e->getMessage() . "<br/>";
90
    die();
91
}
92
93
$stmt = $dbh->prepare("INSERT INTO test (id, body) VALUES (?, ?)");
94
$stmt->bindParam(1, $id);
95
$stmt->bindParam(2, $body);
96
97
// insert one row
98
$id = 3;
99
$body = 'Some other test msg';
100
$stmt->execute();
101
102
// insert another row with different values
103
$id = 4;
104
$body = 'Some other test msg 2';
105
$stmt->execute();
106
$dbh = null;
107
108
class Model {
109
110
111
112
	function __construct()
0 ignored issues
show
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
113
	{
114
		/**
115
        * Load the environment variables
116
        * @return connection object
117
        */
118
        $this->loadDotenv();
119
120
        $this->database = getenv('DB_DATABASE');
121
        $this->host = getenv('DB_host');
122
        $this->username = getenv('DB_USERNAME');
123
        $this->password = getenv('DB_PASSWORD');
124
        $this->driver = getenv('DB_CONNECTION');
125
126
	}
127
	/**
128
    * use vlucas dotenv to access the .env file
129
    **/
130
    protected function loadDotenv()
131
    {
132
        if(getenv('APP_ENV') !== 'production')
133
        {
134
            $dotenv = new Dotenv(__DIR__);
135
            $dotenv->load();
136
        }
137
    }
138
139
    /**
140
     * Handle dynamic static method calls into the method.
141
     *
142
     * @param  string  $method
143
     * @param  array  $parameters
144
     * @return mixed
145
     */
146
    public static function __callStatic($method, $parameters)
147
    {
148
        $instance = new static;
149
150
        return call_user_func_array([$instance, $method], $parameters);
151
    }	
152
153
}
154
155
156
class MySqlConnector extends DatabaseAdapter implements DatabaseAdapterInterface
157
{
158
    /**
159
     * Establish a database connection.
160
     *
161
     * @param  array  $config
162
     * @return \PDO
163
     */
164
    public function connect(array $config)
165
    {
166
        $dsn = $this->getDsn($config);
167
168
        $options = $this->getOptions($config);
169
170
        // We need to grab the PDO options that should be used while making the brand
171
        // new connection instance. The PDO options control various aspects of the
172
        // connection's behavior, and some might be specified by the developers.
173
        $connection = $this->createConnection($dsn, $config, $options);
174
175
        $collation = $config['collation'];
176
177
        // Next we will set the "names" and "collation" on the clients connections so
178
        // a correct character set will be used by this client. The collation also
179
        // is set on the server but needs to be set here on this client objects.
180
        $charset = $config['charset'];
181
182
        $names = "set names '$charset'".
183
            (! is_null($collation) ? " collate '$collation'" : '');
184
185
        $connection->prepare($names)->execute();
186
187
        return $connection;
188
    }
189
190
    /**
191
     * Create a DSN string from a configuration.
192
     *
193
     * Chooses socket or host/port based on the 'unix_socket' config value.
194
     *
195
     * @param  array   $config
196
     * @return string
197
     */
198
    protected function getDsn(array $config)
199
    {
200
        return $this->configHasSocket($config) ? $this->getSocketDsn($config) : $this->getHostDsn($config);
201
    }
202
203
    /**
204
     * Determine if the given configuration array has a UNIX socket value.
205
     *
206
     * @param  array  $config
207
     * @return bool
208
     */
209
    protected function configHasSocket(array $config)
210
    {
211
        return isset($config['unix_socket']) && ! empty($config['unix_socket']);
212
    }
213
214
    /**
215
     * Get the DSN string for a socket configuration.
216
     *
217
     * @param  array  $config
218
     * @return string
219
     */
220
    protected function getSocketDsn(array $config)
221
    {
222
        return "mysql:unix_socket={$config['unix_socket']};dbname={$config['database']}";
223
    }
224
225
    /**
226
     * Get the DSN string for a host / port configuration.
227
     *
228
     * @param  array  $config
229
     * @return string
230
     */
231
    protected function getHostDsn(array $config)
232
    {
233
        extract($config, EXTR_SKIP);
234
235
        return isset($port)
236
                        ? "mysql:host={$host};port={$port};dbname={$database}"
237
                        : "mysql:host={$host};dbname={$database}";
238
    }
239
}
240
241
242
interface DatabaseAdapterInterface
243
{
244
    /**
245
     * Establish a database connection.
246
     *
247
     * @param  array  $config
248
     * @return \PDO
249
     */
250
    public function connect(array $config);
251
}
252
253
254
class DatabaseConnection
255
{
256
    /**
257
     * [$instance description]
258
     * @var [type]
259
     */
260
    private static $instance;
261
262
    /**
263
     * [$databaseConnection description]
264
     * @var [type]
265
     */
266
    private $databaseConnection;
267
268
    /**
269
     * The default PDO connection options.
270
     *
271
     * @var array
272
     */
273
    protected $options = [
274
        PDO::ATTR_CASE => PDO::CASE_NATURAL,
275
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
276
        PDO::ATTR_ORACLE_NULLS => PDO::NULL_NATURAL,
277
        PDO::ATTR_STRINGIFY_FETCHES => false,
278
        PDO::ATTR_EMULATE_PREPARES => false,
279
    ];
280
281
    /**
282
     * Singleton Class:
283
     * Constructor reads database config file and  creates connection.
284
     */
285
    private function __construct(DatabaseConnectionStringFactoryInterface $dbConnStringFactory)
286
    {
287
        //Read config file
288
        $this->config = parse_ini_file('config.ini');
289
        $dsn = $dbConnStringFactory->createDatabaseSourceString($this->config);
290
        $this->createConnection($dsn, $this->options);
291
    }
292
   
293
    public static function getInstance()
294
    {
295
        if (self::$instance === null) {
296
            self::$instance = new self(new DatabaseConnectionStringFactory);
297
        }
298
        return self::$instance;
299
    }
300
    
301
302
    /**
303
     * Create a new PDO connection.
304
     *
305
     * @param  string  $dsn
306
     * @param  array   $config
307
     * @return \PDO
308
     */
309
    public function createConnection($dsn, array $config)
310
    {
311
        $username = $this->config['USERNAME'];
312
313
        $password = $this->config['PASSWORD'];
314
315
        try {
316
            $pdo = new PDO($dsn, $username, $password, $options);
317
        } catch (Exception $e) {
318
            $pdo = $this->tryAgainIfCausedByLostConnection(
319
                $e, $dsn, $username, $password, $options
320
            );
321
        }
322
323
        return $pdo;
324
    }
325
326
    /**
327
     * Get the default PDO connection options.
328
     *
329
     * @return array
330
     */
331
    public function getDefaultOptions()
332
    {
333
        return $this->options;
334
    }
335
336
    /**
337
     * Set the default PDO connection options.
338
     *
339
     * @param  array  $options
340
     * @return void
341
     */
342
    public function setDefaultOptions(array $options)
343
    {
344
        $this->options = $options;
345
    }
346
347
    /**
348
     * Handle a exception that occurred during connect execution.
349
     *
350
     * @param  \Exception  $e
351
     * @param  string  $dsn
352
     * @param  string  $username
353
     * @param  string  $password
354
     * @param  array   $options
355
     * @return \PDO
356
     *
357
     * @throws \Exception
358
     */
359
    protected function tryAgainIfCausedByLostConnection(Exception $e, $dsn, $username, $password, $options)
360
    {
361
        if ($this->causedByLostConnection($e)) {
362
            return new PDO($dsn, $username, $password, $options);
363
        }
364
365
        throw $e;
366
    }
367
368
    /**
369
     * Determine if the given exception was caused by a lost connection.
370
     *
371
     * @param  \Exception  $e
372
     * @return bool
373
     */
374
    protected function causedByLostConnection(Exception $e)
375
    {
376
        $message = $e->getMessage();
377
378
        return Helpers::contains($message, [
379
            'server has gone away',
380
            'no connection to the server',
381
            'Lost connection',
382
            'is dead or not enabled',
383
            'Error while sending',
384
            'decryption failed or bad record mac',
385
            'SSL connection has been closed unexpectedly',
386
            'Deadlock found when trying to get lock',
387
        ]);
388
    }
389
}
390
391
392
class Helpers {
393
394
	/**
395
     * Determine if a given string contains a given substring.
396
     *
397
     * @param  string  $haystack
398
     * @param  string|array  $needles
399
     * @return bool
400
     */
401
    public static function contains($haystack, $needles)
402
    {
403
        foreach ((array) $needles as $needle) {
404
            if ($needle != '' && strpos($haystack, $needle) !== false) {
405
                return true;
406
            }
407
        }
408
409
        return false;
410
    }
411
}