1--TEST-- 2mysqli_set_local_infile_handler() 3--SKIPIF-- 4<?php 5require_once('skipif.inc'); 6require_once('skipifemb.inc'); 7require_once('skipifconnectfailure.inc'); 8 9if (!function_exists('mysqli_set_local_infile_handler')) 10 die("skip - function not available."); 11 12require_once('connect.inc'); 13if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) 14 die("skip Cannot connect to MySQL"); 15 16include_once("local_infile_tools.inc"); 17if ($msg = check_local_infile_support($link, $engine)) 18 die(sprintf("skip %s, [%d] %s", $msg, $link->errno, $link->error)); 19 20mysqli_close($link); 21?> 22--INI-- 23mysqli.allow_local_infile=1 24--FILE-- 25<?php 26 require_once('connect.inc'); 27 require_once('local_infile_tools.inc'); 28 require_once('table.inc'); 29 30 function callback_simple($fp, &$buffer, $buflen, &$error) { 31 static $invocation = 0; 32 33 printf("Callback: %d\n", $invocation); 34 35 $invocation++; 36 if (!is_resource($fp)) 37 printf("[012] First argument passed to callback is not a resource but %s/%s\n", 38 $fp, gettype($fp)); 39 40 if (!$buffer = fread($fp, $buflen)) { 41 if ($invocation == 1) { 42 printf("[013] Cannot read from stream\n"); 43 $error = 'Cannot read from stream'; 44 } else { 45 return strlen($buffer); 46 } 47 } 48 49 $lines = explode("\n", $buffer); 50 if (count($lines) != 4 && strlen($buffer) > 0) { 51 printf("[014] Test is too simple to handle a buffer of size %d that cannot hold all lines\n", $buflen); 52 $error = 'Parser too simple'; 53 } 54 55 $buffer = ''; 56 foreach ($lines as $k => $line) { 57 if ('' === trim($line)) 58 continue; 59 60 $columns = explode(';', $line); 61 if (empty($columns)) { 62 printf("[015] Cannot parse columns\n"); 63 $error = 'Cannot parse columns'; 64 } 65 66 // increase id column value 67 $columns[0] += 1; 68 $buffer .= implode(';', $columns); 69 $buffer .= "\n"; 70 } 71 72 return strlen($buffer); 73 } 74 75 function callback_fclose($fp, &$buffer, $buflen, &$error) { 76 static $invocation = 0; 77 78 printf("Callback: %d\n", $invocation++); 79 80 fclose($fp); 81 return strlen($buffer); 82 } 83 84 function callback_closefile($fp, &$buffer, $buflen, &$error) { 85 static $invocation = 0; 86 87 printf("Callback: %d\n", $invocation++); 88 flush(); 89 if (is_resource($fp)) 90 fclose($fp); 91 $buffer = "1;'a';\n"; 92 if ($invocation > 10) 93 return 0; 94 95 return strlen($buffer); 96 } 97 98 function callback_invalid_args($fp, &$buffer, $buflen) { 99 static $invocation = 0; 100 101 printf("Callback: %d\n", $invocation++); 102 $buffer = fread($fp, $buflen); 103 104 return strlen($buffer); 105 } 106 107 function callback_error($fp, &$buffer, $buflen, &$error) { 108 static $invocation = 0; 109 110 printf("Callback: %d\n", $invocation++); 111 $buffer = fread($fp, $buflen); 112 $error = 'How to access this error?'; 113 114 return -1; 115 } 116 117 if (!is_null($tmp = @mysqli_set_local_infile_handler())) 118 printf("[001] Expecting NULL/NULL got %s/%s\n", $tmp, gettype($tmp)); 119 120 $handle = null; 121 if (!is_null($tmp = @mysqli_set_local_infile_handler($handle))) 122 printf("[002] Expecting NULL/NULL got %s/%s\n", $tmp, gettype($tmp)); 123 124 $handle = @new mysqli(); 125 if (!is_null($tmp = @mysqli_set_local_infile_handler($handle, 'callback_simple'))) 126 printf("[003] Expecting NULL/NULL got %s/%s\n", $tmp, gettype($tmp)); 127 128 if (false !== ($tmp = @mysqli_set_local_infile_handler($link, 'unknown'))) 129 printf("[004] Expecting false/boolean got %s/%s\n", $tmp, gettype($tmp)); 130 131 $file = create_standard_csv(5); 132 133 $expected = array( 134 array('id' => 98, 'label' => 'x'), 135 array('id' => 99, 'label' => 'y'), 136 array('id' => 100, 'label' => 'z'), 137 ); 138 try_handler(10, $link, $file, 'callback_simple', $expected); 139 140 $expected = array(); 141 try_handler(20, $link, $file, 'callback_fclose', $expected); 142 143 // FIXME - TODO - KLUDGE - 144 // IMHO this is wrong. ext/mysqli should bail as the function signature 145 // is not complete. That's a BC break, OK, but it makes perfectly sense. 146 $expected = array(); 147 try_handler(30, $link, $file, 'callback_invalid_args', $expected); 148 149 $expected = array(); 150 try_handler(40, $link, $file, 'callback_error', $expected); 151 152 153 mysqli_close($link); 154 155 if (!is_null($tmp = @mysqli_set_local_infile_handler($link, 'callback_simple'))) 156 printf("[300] Expecting NULL/NULL got %s/%s\n", $tmp, gettype($tmp)); 157 158 print "done!"; 159?> 160--CLEAN-- 161<?php 162 require_once("clean_table.inc"); 163?> 164--EXPECTF-- 165Callback set to 'callback_simple' 166Callback: 0 167Callback: 1 168Callback set to 'callback_fclose' 169Callback: 0 170[022] LOAD DATA failed, [2000] File handle close%s 171Callback set to 'callback_invalid_args' 172Callback: 0 173Callback: 1 174[037] More results than expected! 175array(2) { 176 [%u|b%"id"]=> 177 %unicode|string%(2) "97" 178 [%u|b%"label"]=> 179 %unicode|string%(1) "x" 180} 181array(2) { 182 [%u|b%"id"]=> 183 %unicode|string%(2) "98" 184 [%u|b%"label"]=> 185 %unicode|string%(1) "y" 186} 187array(2) { 188 [%u|b%"id"]=> 189 %unicode|string%(2) "99" 190 [%u|b%"label"]=> 191 %unicode|string%(1) "z" 192} 193Callback set to 'callback_error' 194Callback: 0 195[042] LOAD DATA failed, [2000] How to access this error? 196done!