25
25
use mysqli ;
26
26
use mysqli_stmt ;
27
27
use Symfony \Component \Process \ExecutableFinder ;
28
+ use Symfony \Component \Process \Process ;
28
29
29
30
/**
30
31
* DB-driver for MySQL using the php-mysqli-interface.
@@ -38,8 +39,6 @@ class MysqliDriver extends DriverAbstract
38
39
39
40
private ?mysqli $ linkDB ; //DB-Link
40
41
41
- private ?ConnectionParameters $ config ;
42
-
43
42
private string $ dumpBin = 'mysqldump ' ; // Binary to dump db (if not in path, add the path here)
44
43
45
44
private string $ restoreBin = 'mysql ' ; // Binary to dump db (if not in path, add the path here)
@@ -62,7 +61,7 @@ public function dbconnect(ConnectionParameters $params): bool
62
61
}
63
62
64
63
// Save connection-details
65
- $ this ->config = $ params ;
64
+ $ this ->setConfig ( $ params) ;
66
65
67
66
$ this ->linkDB = new mysqli (
68
67
$ this ->config ->getHost (),
@@ -500,27 +499,31 @@ public function encloseTableName(string $table): string
500
499
*/
501
500
public function dbExport (string &$ fileName , array $ tables ): bool
502
501
{
503
- $ tablesString = implode (' ' , $ tables );
504
- $ paramPass = '' ;
505
-
506
- if ($ this ->config ->getPassword () !== '' ) {
507
- $ paramPass = " -p \"" . $ this ->config ->getPassword () . "\"" ;
508
- }
509
-
510
502
$ dumpBin = (new ExecutableFinder ())->find ($ this ->dumpBin );
503
+ $ dumpParams = [
504
+ $ dumpBin ,
505
+ '-h ' , escapeshellarg ($ this ->config ->getHost ()),
506
+ '-u ' , escapeshellarg ($ this ->config ->getUsername ()),
507
+ ($ this ->config ->getPassword () === '' ) ? '' : '-p ' . escapeshellarg ($ this ->config ->getPassword ()),
508
+ '-P ' , $ this ->config ->getPort (),
509
+ escapeshellarg ($ this ->config ->getDatabase ()),
510
+ implode (' ' , array_map ('escapeshellarg ' , $ tables ))
511
+ ];
511
512
513
+ $ mysqldumpCommand = implode (' ' , $ dumpParams );
512
514
if ($ this ->handlesDumpCompression ()) {
513
515
$ fileName .= '.gz ' ;
514
- $ command = $ dumpBin . ' -h ' . $ this ->config ->getHost () . ' -u ' . $ this ->config ->getUsername (
515
- ) . $ paramPass . ' -P ' . $ this ->config ->getPort () . ' ' . $ this ->config ->getDatabase (
516
- ) . ' ' . $ tablesString . " | gzip > \"" . $ fileName . "\"" ;
516
+ $ pattern = '%s | gzip > %s ' ;
517
517
} else {
518
- $ command = $ dumpBin . ' -h ' . $ this ->config ->getHost () . ' -u ' . $ this ->config ->getUsername (
519
- ) . $ paramPass . ' -P ' . $ this ->config ->getPort () . ' ' . $ this ->config ->getDatabase (
520
- ) . ' ' . $ tablesString . " > \"" . $ fileName . "\"" ;
518
+ $ pattern = '%s > %s ' ;
521
519
}
522
520
523
- $ this ->runCommand ($ command );
521
+ $ process = new Process ([
522
+ 'bash ' , '-c ' ,
523
+ sprintf ($ pattern , $ mysqldumpCommand , escapeshellarg ($ fileName ))
524
+ ]);
525
+
526
+ $ this ->runProcess ($ process , 'Database import failed: ' );
524
527
525
528
return true ;
526
529
}
@@ -530,33 +533,44 @@ public function dbExport(string &$fileName, array $tables): bool
530
533
*/
531
534
public function dbImport (string $ fileName ): bool
532
535
{
533
- $ paramPass = '' ;
534
-
535
- if ($ this ->config ->getPassword () !== '' ) {
536
- $ paramPass = " -p \"" . $ this ->config ->getPassword () . "\"" ;
536
+ if (!in_array (pathinfo ($ fileName , PATHINFO_EXTENSION ), ['sql ' , 'gz ' ])) {
537
+ throw new \RuntimeException (trim ($ fileName . ' is not a valid import file ' ));
537
538
}
538
539
539
540
$ restoreBin = (new ExecutableFinder ())->find ($ this ->restoreBin );
540
541
542
+ $ restoreParams = [
543
+ $ restoreBin ,
544
+ '-h ' , escapeshellarg ($ this ->config ->getHost ()),
545
+ '-u ' , escapeshellarg ($ this ->config ->getUsername ()),
546
+ ($ this ->config ->getPassword () === '' ) ? '' : '-p ' . escapeshellarg ($ this ->config ->getPassword ()),
547
+ '-P ' , $ this ->config ->getPort (),
548
+ escapeshellarg ($ this ->config ->getDatabase ()),
549
+ ];
550
+
551
+ $ mysqlCommand = implode (' ' , $ restoreParams );
541
552
if ($ this ->handlesDumpCompression () && pathinfo ($ fileName , PATHINFO_EXTENSION ) === 'gz ' ) {
542
- $ command = " gunzip -c \"" . $ fileName . "\" | " . $ restoreBin . ' -h ' . $ this -> config -> getHost (
543
- ) . ' -u ' . $ this -> config -> getUsername () . $ paramPass . ' -P ' . $ this -> config -> getPort (
544
- ) . ' ' . $ this -> config -> getDatabase ( );
553
+ $ fileCommand = sprintf ( ' gunzip -c %s ' , escapeshellarg ( $ fileName ));
554
+ } elseif ( pathinfo ( $ fileName , PATHINFO_EXTENSION ) === ' sql ' ) {
555
+ $ fileCommand = sprintf ( ' cat %s ' , escapeshellarg ( $ fileName ) );
545
556
} else {
546
- $ command = $ restoreBin . ' -h ' . $ this ->config ->getHost () . ' -u ' . $ this ->config ->getUsername (
547
- ) . $ paramPass . ' -P ' . $ this ->config ->getPort () . ' ' . $ this ->config ->getDatabase (
548
- ) . " < \"" . $ fileName . "\"" ;
557
+ throw new \RuntimeException (trim ($ fileName . ' is not a valid import file ' ));
549
558
}
550
559
551
- $ this ->runCommand ($ command );
560
+ $ process = new Process ([
561
+ 'bash ' , '-c ' ,
562
+ sprintf ('%s | %s ' , $ fileCommand , $ mysqlCommand )
563
+ ]);
564
+
565
+ $ this ->runProcess ($ process , 'Database import failed: ' );
552
566
553
567
return true ;
554
568
}
555
569
556
570
/**
557
571
* Prepares a statement or uses an instance from the cache.
558
572
*/
559
- private function getPreparedStatement (string $ query ): mysqli_stmt | false
573
+ private function getPreparedStatement (string $ query ): mysqli_stmt | false
560
574
{
561
575
$ name = md5 ($ query );
562
576
@@ -587,7 +601,7 @@ private function getPreparedStatement(string $query): mysqli_stmt | false
587
601
588
602
public function escape (mixed $ value ): string
589
603
{
590
- return str_replace ("\\" , "\\\\" , (string ) $ value );
604
+ return str_replace ("\\" , "\\\\" , (string )$ value );
591
605
}
592
606
593
607
public function getJsonColumnExpression (string $ column , string $ key ): string
0 commit comments