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教程。