表格结构:8列简单员工信息表
CREATE TABLE `emp2` (
`empno` int(11) NOT NULL,
`ename` text,
`job` text,
`mgr` int(11) DEFAULT NULL,
`hiredate` text,
`sal` double DEFAULT NULL,
`comm` double DEFAULT NULL,
`deptno` int(11) DEFAULT NULL,
PRIMARY KEY (`empno`),
UNIQUE KEY `pk_emp` (`empno`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
测试 csvfile:测试 emp.csv 文件
7369,SMITH,CLERK,7902,"1980-12-23 00:00:00",800,,20
7499,ALLEN,SALSMAN,7698,"1980-12-23 00:00:00",1600,300,30
7521,WARD,SALESMAN,7698,"1980-12-23 00:00:00",1250,500,30
php 脚本:我删除了大部分异常代码以使其更短 我可以理解 array_unshift($row ,$fmt) 是让 $row 如下所示,所以有效数据是从位置 1 到 8 。
array(9) {
[0] =>
string(8) "ssssssss"
[1] =>
string(4) "7934"
[2] =>
string(6) "MILLER"
[3] =>
string(5) "CLERK"
[4] =>
string(4) "7782"
[5] =>
string(19) "1980-12-23 00:00:00"
[6] =>
string(4) "1300"
[7] =>
string(0) ""
[8] =>
string(2) "10"
}
<?php
$tname = 'emp';
$fname = 'emp.csv';
$rownum = 0;
function create_insert_stmt($table, $ncols)
{//create insert sql
$stmt = "insert into " . $table . " values(";
foreach (range(1, $ncols) as $i) {
$stmt .= " ? ,";
}
$stmt = preg_replace("/,$/", ');', $stmt);
return $stmt;
}
try {
$db = new mysqli('localhost', 'root', 'root', 'scott');
$db->autocommit(FALSE);
$res = $db->prepare("select * from " . $tname);
$ncols = $res->field_count;
$res->free_result();
$ins = create_insert_stmt($tname, $ncols);
$fmt = str_repeat("s", $ncols);
$res = $db->prepare($ins);
$fp = new SplFileObject($fname, "r");
while ($row = $fp->fgetcsv()) {
if (strlen(implode('', $row)) == 0) continue;
array_unshift($row, $fmt);//put 'ssssssss' into array $row
foreach (range(1, $ncols) as $i) {
$row[$i] =& $row[$i];
//what does this mean ,when i remove & why it can`t work
}
call_user_func_array(array(&$res, "bind_param"), $row);
//the original code is :
//call_user_func_array(array(&$res,"bind_param"),&$row);
//it seems i can`t use &$row in php5.6,so i removed & then it worked fine
$res->execute();
$rownum++;
}
$db->commit();
print $rownum . "rows inserted into " . $tname . "\n<br>";
} catch (Exception $e) {
print "exception:";
die($e->getMessage() . '\n<br>');
}
根据:http://php.net/manual/en/mysqli-stmt.bind-param.php
面向对象风格
bool mysqli_stmt::bind_param ( 字符串 $types , 混合 &$var1 [, 混合 &$... ] ) 程序风格
bool mysqli_stmt_bind_param(mysqli_stmt $stmt,字符串$types,混合&$var1 [,混合&$...])
bind_param函数的参数都是引用,
所以,很明显 $row[$i]=&$row[$i] 正在获取自身的引用。
令我困惑的是:获取自身的参考到底是什么? 是写时复制吗?或者初始化内存中的数组? $row是由$fp->getcsv()生成的,所以它应该已经存在于内存中