PHPCSV教程展示了如何在PHP中处理CSV数据。
$ php -v php -v PHP 8.1.2 (cli) (built: Aug 8 2022 07:28:23) (NTS) ...
我们使用PHP版本8.1.2。
CSV
CSV(逗号分隔值)是一种非常流行的导入和导出数据格式,用于电子表格和数据库。CSV文件中的每一行都是一条数据记录。每条记录由一个或多个字段组成,以逗号分隔。虽然CSV是一种非常简单的数据格式,但可能存在许多差异,例如不同的分隔符、换行符或引号字符。
fgetcsv从提供的文件指针中读取一行并解析CSV字段。它返回一个包含读取字段的数组。fputcsv获取一组数据并将其作为CSV行写入指定的文件句柄。
league/csv是一个简单的PHP库,用于简化CSV文件的加载以及编写、选择和转换CSV记录。
PHP使用fgetcsv读取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
PHP用fputcsv写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文件。
PHPCSV不同分隔符
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函数的第三个参数是optionaldelimiter,设置字段分隔符(一个字符)。默认为逗号。
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联赛\csv
league\csv是一个用于处理CSV数据的PHP库。
$ composer require league/csv
库是用上面的命令安装的。
首先我们用League\Csv\Reader解析CSV数据进行读取。League\Csv\Statement类是一个约束生成器,用于从League\Csv\Reader创建的CSV文档中选择记录。Statement::process方法处理读取器对象并将找到的记录作为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联盟\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创建一个阅读器对象。然后我们创建一个语句并使用process方法处理读取器对象。对返回的结果集应用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联盟\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);
我们创建阅读器对象并设置标题位置。
$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联盟/csvfetchColumn
可以使用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中的PHPCSV
在下面的示例中,我们从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
GET请求是使用curl创建的。
Symfony中的PHPCSV
在以下示例中,我们从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
我们启动网络服务器。
$ curl localhost:8000/users "First name","Last name",Occupation John,Doe,gardener Lucy,Smith,teacher Brian,Bethamy,programmer
我们使用curl发送GET请求。
Laravel中的PHPCSV
在以下示例中,我们从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教程。
