A. 刚学php的小白,问一下这个查询该怎么写
思路:
先查出上述的二维数据,然后遍历查出的二维数组,根据每条的成员id查询出user_name,添加到查询出的二维数组中,最后在渲染输出
示例:
//获取数据库实例
$dsn='mysql:dbname=test;host=127.0.0.1';
$user='root';
$password='';
try{
$db=newPDO($dsn,$user,$password,array(PDO::MYSQL_ATTR_INIT_COMMAND=>"setnamesutf8"));
}catch(PDOException$e){
echo'Connectionfailed:'.$e->getMessage();
}
//得到的二维数组
$data=[
[
'id'=>'1',
'range'=>'所在部门以及下级部门',
'功能项'=>'72',
],
[
'id'=>'1',
'range'=>'所在部门以及下级部门',
'功能项'=>'78,72',
],
[
'id'=>'10,7',
'range'=>'所在部门以及下级部门',
'功能项'=>'72,82',
],
];
//遍历
foreach($dataas&$item){
$sth=$db->query('selectuser_namefromuserwheremember_idin('.$item['id'].')');
$user=$sth->fetchAll(PDO::FETCH_ASSOC);
$sth->debugDumpParams();
$item['member_name']=implode(',',array_column($user,'user_name'));
}
unset($item);
var_mp($data);
输出
array(3){
[0]=>
array(4){
["id"]=>
string(1)"1"
["range"]=>
string(30)"所在部门以及下级部门"
["功能项"]=>
string(2)"72"
["member_name"]=>
string(6)"李明"
}
[1]=>
array(4){
["id"]=>
string(1)"1"
["range"]=>
string(30)"所在部门以及下级部门"
["功能项"]=>
string(5)"78,72"
["member_name"]=>
string(6)"李明"
}
[2]=>
array(4){
["id"]=>
string(4)"10,7"
["range"]=>
string(30)"所在部门以及下级部门"
["功能项"]=>
string(5)"72,82"
["member_name"]=>
string(13)"刘海,达明"
}
}
B. PHP7.0怎么通过打开扩展功能和mysql相连
第一步:进入php源码中的"ext/mysql"目录下
第二步:在当前目录下运行phpize命令:/usr/local/php524/bin/phpize
phpize的规则:去哪个目录下运行phpize文件,那么就会在该目录下生成一个configure文件。
第三步:运行刚才生成的configure文件
命令: ./configure --with-php-config=/usr/local/php524/bin/php-config --with-mysql=/usr/local/mysql/
这里最关键的是通过--with-mysql参数告诉mysql客户端的位置。这样才能生成mysql.so。
实验的时候,没有加这个参数,结果错误:
./configure --with-php-config=/usr/local/php524/bin/php-config
第四步:编译生成.so文件
第五步:配置php引擎加载该扩展。
补充一下:就是去php.ini文件中修改一下配置,加载mysql.so这个扩展(这个扩展文件要放到php指定的扩展目录下面去)
第六步:测试php引擎是否成功加载该扩展编写文件phpinfo.php,内容是:<?phpehco phpinfo();?>
运行后,可以看到有如下信息显示:mysqlMySQLSupport enabledActive PersistentLinks 0
Active Links 0
Client API version 5.1.55
MYSQL_MODULE_TYPE no value
MYSQL_SOCKET /tmp/mysql.sock
MYSQL_INCLUDE no value
MYSQL_LIBS no value
通过这样的方式可以确认,php引擎已经成功加载了mysql.so扩展。
第七步:已经生成的mysql.so。编写php代码测试是否能连接mysql。
C. php pdo 怎么获取查询出来的结果集
php使用PDO抽象层获取查询结果,主要有三种方式:
(1)PDO::query()查询。
看下面这段php代码:
<?php //PDO::query()查询
$res = $db->query('select * from user');
$res->setFetchMode(PDO::FETCH_NUM); //数字索引方式
while ($row = $res->fetch()){
print_r($row);
}
?>
(2)PDO->exec()处理sql
<?php //PDO->exec()处理sql
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$res = $db->exec("insert into user(id,name) values('','php点点通')");
echo $res;
?>
(3)PDO::prepare()预处理执行查询
<?php //PDO::prepare()预处理执行查询
$res = $db->prepare("select * from user");
$res->execute();
while ($row = $res->fetchAll()) {
print_r($row);
}
?>
setAttribute() 方法是设置属性,常用参数如下:
PDO::CASE_LOWER -- 强制列名是小写
PDO::CASE_NATURAL -- 列名按照原始的方式
PDO::CASE_UPPER -- 强制列名为大写
setFetchMode方法来设置获取结果集的返回值的类型,常用参数如下:
PDO::FETCH_ASSOC -- 关联数组形式
PDO::FETCH_NUM -- 数字索引数组形式
PDO::FETCH_BOTH -- 两者数组形式都有,这是默认的
PDO::FETCH_OBJ -- 按照对象的形式,类似于以前的 mysql_fetch_object()
对上面总结如下:
查询操作主要是PDO::query()、PDO::exec()、PDO::prepare()。
PDO->query() — 处理一条SQL语句,并返回一个“PDOStatement”
PDO->exec() — 处理一条SQL语句,并返回所影响的条目数
PDO::prepare()主要是预处理操作,需要通过$rs->execute()来执行预处理里面的SQL语句
最后介绍两个常用的函数:
(1)fetchColumn()获取指定记录里一个字段结果,默认是第一个字段!
<?php
$res = $db->query('select * from user');
//获取指定记录里第二个字段结果
$col = $res->fetchColumn(1);
echo $col;
?>
(2)fetchAll(),从一个结果集中获取数据,然后存放在关联数组中
<?php
$res = $db->query('select * from user');
$res_arr =$res->fetchAll();
print_r($res_arr);
?>
D. 请教高手:php实现n叉树遍历
要构建的无限分类的模型. 电子产品是最大的分类.家用电器 ,数码产品是其子分类.可以看到子分类是被父分类包含起来的.每个分类都有左右 两个节点编号分别是1、2、3.....
根据上面的图mysql中建立表和插入数据
CREATE TABLE `proct_categories` (
`id` MEDIUMINT( 8 ) NOT NULL AUTO_INCREMENT PRIMARY KEY ,`name` VARCHAR( 20 ) NOT NULL ,
`left_node` MEDIUMINT( 8 ) NOT NULL ,
`right_node` MEDIUMINT( 8 ) NOT NULL
) ENGINE = MYISAM CHARACTER SET utf8 COLLATE utf8_general_ci;INSERT INTO `proct_categories` (`id`, `name`, `left_node`, `right_node`) VALUES(1, '电子产品', 1, 20),
(2, '家用电器', 2, 9),
(3, '电视机', 3, 4),
(4, '电冰箱', 5, 6),
(5, '空调', 7, 8),
(6, '数码产品', 10, 19),
(7, '电脑', 11, 18),
(8, '台式电脑', 12, 13),
(9, '笔记本电脑', 14, 15),
(10, '平板电脑', 16, 17);
表结构如下:
下面是PHP的实例代码:
1、获取所有节点
<?php
$pdo = new PDO(
'mysql:host=localhost;dbname=test',
'root',
''
);
$pdo->exec("SET NAMES UTF8");
$stmt = $pdo->prepare("SELECT c.name FROM proct_categories as c, proct_categories as pWHERE c.left_node BETWEEN p.left_node AND p.right_nodeAND p.name='电子产品' ORDER BY c.left_node");$stmt->execute();
$rs=$stmt->fetchAll(PDO::FETCH_ASSOC);
foreach($rs as $v){
echo $v['name'].'<br />';
}
输出:
电子产品
家用电器
电视机
电冰箱
空调
数码产品
电脑
台式电脑
笔记本电脑
平板电脑
2、 获取某个父节点以及其所有子节点
<?php
$pdo = new PDO(
'mysql:host=localhost;dbname=test',
'root',
''
);
$pdo->exec("SET NAMES UTF8");
$stmt = $pdo->prepare("SELECT c.name FROM proct_categories as c, proct_categories as pWHERE c.left_node BETWEEN p.left_node AND p.right_nodeAND p.name='数码产品' ORDER BY c.left_node");$stmt->execute();
$rs=$stmt->fetchAll(PDO::FETCH_ASSOC);
foreach($rs as $v){
echo $v['name'].'<br />';
}
输出:
数码产品
电脑
台式电脑
笔记本电脑
平板电脑
3、获取所有的叶子节点
<?php
$pdo = new PDO(
'mysql:host=localhost;dbname=test',
'root',
''
);
$pdo->exec("SET NAMES UTF8");
$stmt = $pdo->prepare("SELECT name FROM proct_categories where right_node-left_node=1");$stmt->execute();
$rs=$stmt->fetchAll(PDO::FETCH_ASSOC);
foreach($rs as $v){
echo $v['name'].'<br />';
}
输出:
电视机
电冰箱
空调
台式电脑
笔记本电脑
平板电脑
4、获取某个子节点及其所有父节点
<?php
$pdo = new PDO(
'mysql:host=localhost;dbname=test',
'root',
''
);
$pdo->exec("SET NAMES UTF8");
$stmt = $pdo->prepare("SELECT p.name FROM proct_categories AS c, proct_categories AS p WHERE c.left_node BETWEEN p.left_node AND p.right_node AND c.name = '平板电脑' ORDER BY p.left_node");$stmt->execute();
$rs=$stmt->fetchAll(PDO::FETCH_ASSOC);
foreach($rs as $v){
echo $v['name'].'<br />';
}
输出:
电子产品
数码产品
电脑
平板电脑
5、获取所有节点极其所处的层级
<?php
$pdo = new PDO(
'mysql:host=localhost;dbname=test',
'root',
''
);
$pdo->exec("SET NAMES UTF8");
$stmt = $pdo->prepare("SELECT c.name, (COUNT(p.name) - 1) AS level FROM proct_categories AS c, proct_categories AS p WHERE c.left_node BETWEEN p.left_node AND p.right_node GROUP BY c.name ORDER BY c.left_node");$stmt->execute();
$rs=$stmt->fetchAll(PDO::FETCH_ASSOC);
var_mp($rs);
echo '<br />';
foreach($rs as $v){
echo $v['name'].' level:'.$v['level'].'<br />';}
输出:
电子产品 level:0
家用电器 level:1
电视机 level:2
电冰箱 level:2
空调 level:2
数码产品 level:2
电脑 level:2
台式电脑 level:3
笔记本电脑 level:3
平板电脑 level:3
6、获取某个节点的层级
<?php
$pdo = new PDO(
'mysql:host=localhost;dbname=test',
'root',
''
);
$pdo->exec("SET NAMES UTF8");
$stmt = $pdo->prepare("SELECT c.name, (COUNT(p.name) - 1) AS level FROM proct_categories AS c, proct_categories AS p WHERE c.left_node BETWEEN p.left_node AND p.right_node and c.name='平板电脑' GROUP BY c.name ORDER BY c.left_node");$stmt->execute();
$rs=$stmt->fetchAll(PDO::FETCH_ASSOC);
var_mp($rs);
echo '<br />';
foreach($rs as $v){
echo $v['name'].' level:'.$v['level'].'<br />';}
输出:
平板电脑 level:3
7、在某个节点后平行的插入一个节点
<?php
$pdo = new PDO(
'mysql:host=localhost;dbname=test',
'root',
''
);
$pdo->exec("SET NAMES UTF8");
function addNode($left_node,$new_node){
global $pdo;
$stmt = $pdo->prepare("SELECT right_node FROM proct_categories WHERE name = '$left_node'");$stmt->execute();
$rs=$stmt->fetch(PDO::FETCH_ASSOC);
$right_node=$rs['right_node'];
$pdo->exec("UPDATE proct_categories SET right_node = right_node + 2 WHERE right_node > $right_node");$pdo->exec("UPDATE proct_categories SET left_node = left_node + 2 WHERE left_node > $right_node");$pdo->exec("INSERT INTO proct_categories(name, left_node, right_node) VALUES('$new_node', $right_node + 1, $right_node + 2)");}
addNode('家用电器','办公用品');
完成之后表结构如下:
8、删除某个节点及其所有子节点
<?php
$pdo = new PDO(
'mysql:host=localhost;dbname=test',
'root',
''
);
$pdo->exec("SET NAMES UTF8");
function deleteNode($node_name){
global $pdo;
$stmt = $pdo->prepare("SELECT left_node,right_node, right_node - left_node + 1 as width FROM proct_categories WHERE name ='$node_name'");$stmt->execute();
$rs=$stmt->fetch(PDO::FETCH_ASSOC);
$left_node=$rs['left_node'];
$right_node=$rs['right_node'];
$width=$rs['width'];
$pdo->exec("DELETE FROM proct_categories WHERE left_node BETWEEN $left_node AND $right_node");$pdo->exec("UPDATE proct_categories SET right_node = right_node - $width WHERE right_node > $right_node");$pdo->exec("UPDATE proct_categories SET left_node = left_node - $width WHERE left_node > $right_node");}
deleteNode('数码产品');
完成之后表结构如下:
可以看到用多叉树的方式构建无限分类,查询的时候是非常简便的.但是在插入新的节点和删除节点时就比较麻烦了.
E. php 如何从数据里选择所需要信息然后生成csv文件自动保存在指定的路径(不提示保存,自动)
命令行模式下,或者web模式下保存的路径在服务器中,可以达到你的要求(有该路径的权限即可)
如果是在web模式下,不提示直接保存到访客的电脑中的某个位置,是不可以的。
web模式保存到客户端,只能通过下载,由用户指定,或保存到默认的下载目录。
以下是代码示例:
$dsn='mysql:dbname=testdb;host=127.0.0.1';
$user='dbuser';
$password='dbpass';
//连接数据库pdo
try{
$dbh=newPDO($dsn,$user,$password,array(PDO::MYSQL_ATTR_INIT_COMMAND=>"SETNAMES'UTF8'"));
}catch(PDOException$e){
echo'Connectionfailed:'.$e->getMessage();exit;
}
//读取数据,具体sql你根据情况修改
$stat=$dbh->prepare('SELECT*FROM`table`WHERE`id`>0LIMIT100;');
$stat->execute();
$result=$stat->fetchAll(PDO::FETCH_ASSOC);
//创建csv文件并打开文件指针
$filepath='file.csv';
$fp=fopen($filepath,'w');
//写入数据
foreach($resultas$i=>$row){
//写入标题行
if($i==0){
fputcsv($fp,array_keys($row));
}
fputcsv($fp,$row);
}
//关闭文件指针
fclose($fp);
//把文件输出到下载
$file=fopen($filepath,"r");//打开文件
$size=filesize($filepath);
Header("Content-type:application/octet-stream");
Header("Accept-Ranges:bytes");
Header("Accept-Length:".$size);
Header("Content-Disposition:attachment;filename=download.csv");
echofread($file,$size);
fclose($file);
相关知识点:
PHP: fputcsv
PHP:PDO
数据库查询的时候只返回列名,防止列出现重复,csv里会有重复的数据