PHP CSV
最后修改于 2025 年 2 月 16 日
PHP CSV 教程演示了如何在 PHP 中使用 CSV 数据。
CSV
CSV (逗号分隔值) 是一种非常流行的导入和导出数据格式,用于电子表格和数据库。CSV 文件中的每一行都是一条数据记录。每条记录由一个或多个字段组成,字段之间用逗号分隔。虽然 CSV 是一种非常简单的数据格式,但可能存在许多差异,例如不同的分隔符、换行符或引用字符。
fgetcsv 从给定的文件指针中读取一行,并解析 CSV 字段。它返回一个包含读取字段的数组。fputcsv 接受一个数据数组,并将其作为 CSV 行写入指定的文件句柄。
league/csv 是一个简单的 PHP 库,用于简化 CSV 文档的加载以及编写、选择和转换 CSV 记录。
使用 fgetcsv 读取 PHP CSV
下面的例子使用内置的 fgetcsv 函数来读取 CSV 数据。
John,Doe,gardener Lucy,Smith,teacher Brian,Bethamy,programmer
这是 users.csv 文件。
<?php
$f = fopen('users.csv', 'r');
while(!feof($f)) {
$row = fgetcsv($f);
if (!empty($row)) {
echo "$row[0] $row[1] is a(n) $row[2]\n";
}
}
fclose($f);
我们从 users.csv 文件中读取数据。
$f = fopen('users.csv', 'r');
使用 fopen,我们打开一个文件句柄到 users.csv 文件。
while(!feof($f)) {
在一个 while 循环中,我们读取所有行直到文件结束。feof 函数检查文件句柄是否到达文件末尾。
$row = fgetcsv($f);
我们使用 fgetcsv 读取一行;该函数返回一个字段数组。
if (!empty($row)) {
echo "$row[0] $row[1] is a(n) $row[2]\n";
}
如果该行不为空,我们将在消息中输出这些字段。
fclose($f);
fclose 函数关闭一个打开的文件指针。
$ php read_data.php John Doe is a(n) gardener Lucy Smith is a(n) teacher Brian Bethamy is a(n) programmer
使用 fputcsv 写入 PHP CSV
下面的例子将 CSV 数据写入一个文件。
<?php
$users = [
['John', 'Doe', 'gardener' ],
['Lucy', 'Smith', 'teacher'],
['Brian', 'Bethamy', 'programmer']
];
$fp = fopen('users.csv', 'w');
foreach ($users as $user) {
fputcsv($fp, $user);
}
fclose($fp);
我们有一个用户数组。我们使用 fputcsv 将用户写入 CSV 文件。
PHP CSV 不同的分隔符
fgetcsv 函数允许读取具有不同分隔符的数据。
John|Doe|gardener Lucy|Smith|teacher Brian|Bethamy|programmer
我们的数据使用 | 字符分隔。
<?php
$f = fopen('users2.csv', 'r');
while(!feof($f)) {
$row = fgetcsv($f, 0, '|');
if (!empty($row)) {
echo "$row[0] $row[1] is a(n) $row[2]\n";
}
}
fclose($f);
fgetcsv 函数的第三个参数是可选的分隔符,它设置字段分隔符(仅一个字符)。默认情况下是逗号。
PHP 发送 CSV 数据
下面的例子将 CSV 数据作为附件发送给用户。
<?php
header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename=users.csv');
$output = fopen('php://output', 'w');
fputcsv($output, ['First name', 'Last name', 'Occupation']);
$f = fopen('users.csv', 'r');
while (!feof($f)) {
$rows[] = fgetcsv($f);
}
foreach ($rows as $row) {
fputcsv($output, $row);
}
fclose($f);
该示例从文件中读取 CSV 并将其返回给用户;用户将该文件作为附件接收。
header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename=users.csv');
这些标头指定内容类型和作为附件的处置方式。
$output = fopen('php://output', 'w');
我们创建一个连接到输出流的文件指针。
fputcsv($output, ['First name', 'Last name', 'Occupation']);
我们将标头字段发送到输出流。
$f = fopen('users.csv', 'r');
while (!feof($f)) {
$rows[] = fgetcsv($f);
}
我们将 CSV 数据读入一个数组。
foreach ($rows as $row) {
fputcsv($output, $row);
}
该数组被写入输出流。
PHP league\csv
league\csv 是一个用于处理 CSV 数据的 PHP 库。
$ composer require league/csv
该库使用上述命令安装。
首先,我们使用 League\Csv\Reader 解析 CSV 数据进行读取。 League\Csv\Statement 类是一个约束构建器,用于从 League\Csv\Reader 创建的 CSV 文档中选择记录。 Statement::process 方法处理 reader 对象并将找到的记录作为 ResultSet 对象返回。我们可以在结果集上执行过滤、区间或排序操作,就像在 SQL 中一样。
我们使用 League\Csv\Writer 进行写入。
'First name','Last name','Occupation' John,Doe,gardener Lucy,Smith,teacher Brian,Bethamy,programmer Lucy,Black,musician Pau,Novak,teacher
我们有这些数据。
PHP league\csv 统计行数
在第一个例子中,我们统计 CSV 文件中可用的行数。
<?php
require __DIR__ . '/vendor/autoload.php';
use League\Csv\Reader;
use League\Csv\Statement;
$reader = Reader::createFromPath('users.csv', 'r');
$rows = Statement::create()->process($reader);
echo count($rows);
我们使用 Reader::createFromPath 创建一个 reader 对象。然后我们创建一个 statement 并使用 process 方法处理 reader 对象。对返回的结果集应用 count 函数将返回行数。
$ php count_rows.php 6
文件中总共有六行,包括标题。
如果我们不想包含标题行,可以使用 setHeaderOffset。
<?php
require __DIR__ . '/vendor/autoload.php';
use League\Csv\Reader;
use League\Csv\Statement;
$reader = Reader::createFromPath('users.csv', 'r');
$reader->setHeaderOffset(0);
$rows = Statement::create()->process($reader);
echo count($rows);
我们统计 CSV 文件中的行数,不包括标题行。
PHP league\csv 读取数据
在下面的例子中,我们使用 league\csv 读取 CSV 数据。
<?php
require __DIR__ . '/vendor/autoload.php';
use League\Csv\Reader;
$csv = Reader::createFromPath('users.csv', 'r');
$csv->setHeaderOffset(0);
$header = $csv->getHeader();
print_r($header);
$records = $csv->getRecords();
print_r(iterator_to_array($records));
echo $csv->getContent();
我们从 users.csv 文件中读取标题和数据。
$csv = Reader::createFromPath('users.csv', 'r');
$csv->setHeaderOffset(0);
我们创建 reader 对象并设置标题位置。
$header = $csv->getHeader(); print_r($header);
我们获取标题行。
$records = $csv->getRecords(); print_r(iterator_to_array($records));
getRecords 方法将所有 CSV 记录作为 Iterator 对象返回。
echo $csv->getContent();
getContent 方法将 CSV 文档作为字符串返回。
$ php read_data2.php
Array
(
[0] => 'First name'
[1] => 'Last name'
[2] => 'Occupation'
)
Array
(
[1] => Array
(
['First name'] => John
['Last name'] => Doe
['Occupation'] => gardener
)
[2] => Array
(
['First name'] => Lucy
['Last name'] => Smith
['Occupation'] => teacher
)
[3] => Array
(
['First name'] => Brian
['Last name'] => Bethamy
['Occupation'] => programmer
)
[4] => Array
(
['First name'] => Lucy
['Last name'] => Black
['Occupation'] => musician
)
[5] => Array
(
['First name'] => Pau
['Last name'] => Novak
['Occupation'] => teacher
)
)
'First name','Last name','Occupation'
John,Doe,gardener
Lucy,Smith,teacher
Brian,Bethamy,programmer
Lucy,Black,musician
Pau,Novak,teacher
PHP league/csv fetchColumn
可以使用 fetchColumn 选择特定的数据列。
<?php
require __DIR__ . '/vendor/autoload.php';
use League\Csv\Reader;
use League\Csv\Statement;
$reader = Reader::createFromPath('users.csv', 'r');
$reader->setHeaderOffset(0);
$records = Statement::create()->process($reader);
foreach ($records->fetchColumn(2) as $value) {
echo $value . "\n";
}
在示例中,我们从数据中获取第三列。
$ php fetch_column.php gardener teacher programmer musician teacher
Slim 中的 PHP CSV
在下面的例子中,我们从一个 Slim 应用程序返回 CSV 数据。
$ composer req slim/slim $ composer req slim/psr7 $ composer req slim/http
我们安装 slim/slim、slim/psr7 和 slim/http 包。
<?php
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Slim\Factory\AppFactory;
use Slim\Psr7\Stream;
require __DIR__ . '/../vendor/autoload.php';
$app = AppFactory::create();
$app->get('/users', function (Request $request, Response $response): Response {
$csv_file = '../users.csv';
$fp = fopen($csv_file);
$stream = new Stream(fopen($csv_file, 'rb'));
return $response->withHeader('Content-Type', 'application/octet-stream')
->withHeader('Content-Disposition', 'attachment; filename=users.csv')
->withHeader('Pragma', 'no-cache')
->withBody($stream);
});
$app->run();
我们从文件中读取数据,并将其发送到响应主体中。
$ php -S localhost:8000 -t public
我们启动内置服务器。
$ curl localhost:8000/users "First name","Last name",Occupation John,Doe,gardener Lucy,Smith,teacher Brian,Bethamy,programmer
使用 curl 创建一个 GET 请求。
Symfony 中的 PHP CSV
在下面的例子中,我们从一个 Symfony 应用程序发送一个 CSV 响应。
$ symfony new symcsv $ cd symcsv
创建一个新项目。
$ composer req maker --dev $ composer req annot
我们安装 maker 和 annot 依赖项。
$ php bin/console make:controller UserController
我们创建 UserController。
<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use App\Service\ContainerParametersHelper;
class UserController extends AbstractController
{
/**
* @Route("/users", name="user")
*/
public function index(): Response
{
$rootDir = $this->getParameter('kernel.project_dir');
$fp = fopen("$rootDir/var/users.csv", 'r');
$response = new Response(stream_get_contents($fp));
fclose($fp);
$response->headers->set('Content-Type', 'text/csv');
$response->headers->set('Pragma', 'no-cache');
$response->headers->set('Content-Disposition',
'attachment; filename="users.csv"');
return $response;
}
}
users.csv 文件位于 var 目录中。我们读取文件的内容,并将其作为附件发送到响应对象中。
$ symfony serve
我们启动 Web 服务器。
$ curl localhost:8000/users "First name","Last name",Occupation John,Doe,gardener Lucy,Smith,teacher Brian,Bethamy,programmer
我们使用 curl 发送一个 GET 请求。
Laravel 中的 PHP CSV
在下面的例子中,我们从一个 Laravel 应用程序发送一个 CSV 响应。
$ laravel new laracsv $ cd laracsv
创建一个新项目。
<?php
use Illuminate\Support\Facades\Route;
use Symfony\Component\HttpFoundation\StreamedResponse;
Route::get('/users', function() : StreamedResponse {
$headers = [
"Content-type" => "text/csv",
"Content-Disposition" => "attachment; filename=users.csv",
"Pragma" => "no-cache",
];
$columns = ['First name', 'Last name', 'Occupation'];
$fileName = storage_path('users.csv');
$f = fopen($fileName, 'r');
while (!feof($f)) {
$rows[] = fgetcsv($f);
}
fclose($f);
return new StreamedResponse(
function() use ($rows) {
$handle = fopen('php://output', 'w');
foreach ($rows as $row) {
if (!empty($row)) {
fputcsv($handle, $row);
}
}
fclose($handle);
},
200,
[
'Content-type' => 'text/csv',
'Content-Disposition' => 'attachment; filename=members.csv'
]
);
});
users.csv 文件位于 storage 目录中。我们读取文件的内容,并将其作为附件发送到响应对象中。
$ php artisan serve
我们启动 Web 服务器并定位到 localhost:8000/users。
来源
在本文中,我们使用纯 PHP、Symfony、Slim 和 Laravel 处理 CSV 数据。
作者
列出所有 PHP 教程。