Bonjour,
Dans un script j'effectue une compression bz2 à la volée pour envoyer un fichier déjà compressé au client.
Dans Symfony2 j'utilise ce code dans un service :
Code php : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72 <?php namespace Acme\ExportTableBundle\Services; use Doctrine\Bundle\DoctrineBundle\Registry; use Symfony\Component\HttpFoundation\StreamedResponse; class PackageTable { public function __construct(Registry $doctrine) { $this->doctrine = $doctrine; } public function package($fqn_table) { list($database, $table) = explode('.', $fqn_table); $connection = $this->doctrine->getConnection($database); $user = $connection->getUsername(); $password = $connection->getPassword(); $proc = proc_open( "mysqldump -u $user -p $database $table", array( 0 => array('pipe', 'r'), 1 => array('pipe', 'w') ), $stream ); if (is_resource($proc)) { fwrite($stream[0], $password); fclose($stream[0]); $dump = $stream[1]; flush(); ob_clean(); $response = new StreamedResponse; $response->setCallback(function () use ($dump) { rewind($dump); $output = fopen('php://output', 'w+'); while (!feof($dump)) { $chunk = fread($dump, 8192); fwrite($output, bzcompress($chunk)); if (empty($chunk)) { break; } } fclose($dump); }); $response->setStatusCode(200); $response->headers->set('Content-Description', 'File Transfer'); $response->headers->set('Content-Type', 'application/x-bzip2'); $response->headers->set('Content-Transfer-Encoding', 'binary'); $response->headers->set('Content-Disposition', "attachment; filename=$table.sql.bz2"); // return $response; $response->send(); } } }
L'erreur qui apparait est :
Un var_dump sur $dump montre que la resource est de type "unknown".
Code : Sélectionner tout - Visualiser dans une fenêtre à part Warning: rewind(): 20 is not a valid stream resource
J'ai donc essayé le code suivant (dont le cœur est identique) pour dégager les responsabilités :
Code php : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55 <?php use Symfony\Component\HttpFoundation\StreamedResponse; require '../vendor/autoload.php'; $fqn_table = 'database_reference_backups.toto_short'; $user = 'root'; $password = '*'; list($database, $table) = explode('.', $fqn_table); $proc = proc_open( "mysqldump -u $user -p $database $table", array( 0 => array('pipe', 'r'), 1 => array('pipe', 'w') ), $stream ); if (is_resource($proc)) { fwrite($stream[0], $password); fclose($stream[0]); $dump = $stream[1]; $response = new StreamedResponse; $response->setCallback(function () use ($dump) { $output = fopen('php://output', 'w+'); while (!feof($dump)) { $chunk = fread($dump, 8192); fwrite($output, bzcompress($chunk)); if (empty($chunk)) { break; } } fclose($dump); }); $response->setStatusCode(200); $response->headers->set('Content-Description', 'File Transfer'); $response->headers->set('Content-Type', 'application/x-bzip2'); $response->headers->set('Content-Transfer-Encoding', 'binary'); $response->headers->set('Content-Disposition', "attachment; filename=$table.sql.bz2"); $response->send(); }
Ce code exécuté seul, fonctionne parfaitement.
Je trouve cela extrêmement étrange, mais visiblement symfony y est pour quelque chose.
Any guess ?
Partager