org.majkel/dbase
Composer 安装命令:
composer require org.majkel/dbase
包简介
Library to access dbase / xbase / dbf database files
README 文档
README
Library for processing dbase tables.
Table of Contents
Supported formats
- dBASE III
- dBASE III PLUS
Supported memo formats
- DBT
- FPT
Installation
Composer
Using composer to install this library is strongly recommended.
composer require org.majkel/dbase
Then in your script use this line of code
require_once 'vendor/autoload.php'
Old-fashion style
Download library and place it somewhere on disk.
Then in your script use this line of code
require_once 'DBASE/LIB/DIR/autoloader.php';
Documentation
Reading tables
Table object is both array accessible and traversable. You can loop over it as collection or read specific record by it's index.
require_once 'vendor/autoload.php' use org\majkel\dbase\Table; $totalSum = 0; $dbf = Table::fromFile('some/table.dbf'); foreach ($dbf as $record) { // returns all records includeing deleted ones if (!$record->isDeleted()) { $totalSum += $record->int_val; } } echo "Total sum is $totalSum, 5th description: {$record[4]['description']}\n";
Inserting rows
You can insert records as record object or as an associative array.
Note that insert operation is not atomic. Use transactions to achieve integrity safety.
require_once 'vendor/autoload.php' use org\majkel\dbase\Table; use org\majkel\dbase\Record; $dbf = Table::fromFile('some/table.dbf'); $record = new Record(); $record->fieldBool = true; $record->fieldInt = 123; $record->fieldChar = 'some text 1'; $record->fieldMemo = 'some long text'; $dbf->insert($record); $dbf->insert([ 'fieldBool' => false, 'fieldInt' => 321, 'fieldChar' => 'some text 2', ]);
Automatic type conversion
Dbase and PHP types are automatically converted during fetching and storing of rows.
| Dbase type | Type name | Possible values | PHP type |
|---|---|---|---|
| C | Character | any string | string |
| D | Date | DDMMYY | DateTime |
| L | Logical | [YTNF?] | boolean |
| M | Memo | any string | string |
| N | Numeric | [-0-9.] | int / float |
Record object
Record is basically ArrayObject. Object that can be treated as array.
Reading data from record
require_once 'vendor/autoload.php' use org\majkel\dbase\Table; $dbf = Table::fromFile('some/table.dbf'); // fetch first record $record = $dbf[0]; echo "int field: {$record->number}\n"; // returns integer echo "bool field: {$record->boolean}\n"; // returns boolean echo "date field: {$record->date->format('Y-m-d')}\n"; // return DateTime object echo "text field: {$record->text}\n"; // returns string echo "memo field: {$record->memo}\n"; // returns string (not entity id) echo "memo field id: {$record->getMemoEntryId('memo')}\n"; // returns entity id for memo field `memo` echo "is record deleted: {$record->isDeleted('memo')}\n"; // returns whether record is deleted // ... or ... echo "int field: {$record['number']}\n"; // returns integer echo "bool field: {$record['boolean']}\n"; // returns boolean echo "date field: {$record['date']->format('Y-m-d')}\n"; // return DateTime object echo "text field: {$record['text']}\n"; // returns string echo "memo field: {$record['memo']}\n"; // returns string (not entity id) echo "memo field id: {$record->getMemoEntryId('memo')}\n"; // returns entity id for memo field `memo` echo "is record deleted: {$record->isDeleted('memo')}\n"; // returns whether record is deleted // you can loop over fields in the record foreach ($record as $fieldName => $fieldValue) { echo "$fieldName = $fieldValue\n"; }
Writing data to record
require_once 'vendor/autoload.php' use org\majkel\dbase\Table; $dbf = Table::fromFile('some/table.dbf'); // fetch first record $record = $dbf[0]; $record->number = 123; $record->boolean = true; $record->date = new DateTime(); $record->text = 'some text'; $record->memo = 'some longer text'; // ... or ... $record['number'] = 123; $record['boolean'] = true; $record['date'] = new DateTime(); $record['text'] = 'some text'; $record['memo'] = 'some longer text';
Updating tables
Note that update operation is not atomic. Use transactions to achieve integrity safety.
require_once 'vendor/autoload.php' use org\majkel\dbase\Table; $dbf = Table::fromFile('some/table.dbf'); foreach ($dbf as $record) { $record->int_val += 10; $dbf->update($record); // header is updated everytime }
Deleting records
Do not use
Record::setDeletedto delete records
require_once 'vendor/autoload.php' use org\majkel\dbase\Table; $dbf = Table::fromFile('some/table.dbf'); // delete 7th record $dbf->delete(6); // undelete 6th record $dbf->markDelete(5, false);
Transactions
Transactions can prevent two processes from updating the same file.
When some process cannot acquire lock on the table exception is being thrown.
Transactions can also save you from unnecessary header updates. Header is updated at the end of transaction.
require_once 'vendor/autoload.php' use org\majkel\dbase\Table; $dbf = Table::fromFile('some/table.dbf'); // header is updated. Transaction flag is set $dbf->beginTransaction(); foreach ($dbf as $record) { $record->int_val += 10; $dbf->update($record); // header is not written } // duplicate last row $dbf->insert($record); // header is not written // header is written, transaction flag is cleared, recond count is updated $dbf->endTransaction();
Defining tables
To construct new table use builder object.
require_once 'vendor/autoload.php' use org\majkel\dbase\Builder; use org\majkel\dbase\Format; use org\majkel\dbase\Field; $table = Builder::create() ->setFormatType(Format::DBASE3) ->addField(Field::create(Field::TYPE_CHARACTER)->setName('str')->setLength(15)) ->addField(Field::create(Field::TYPE_LOGICAL)->setName('bool')) ->addField(Field::create(Field::TYPE_NUMERIC)->setName('num')) ->build('destination.dbf'); for ($i = 1; $i <= 3; ++$i) { $table->insert([ 'str' => "Str $i", 'bool' => false, 'num' => $i, ]); }
Creating table from another table
You can create new table form existing table definition.
require_once 'vendor/autoload.php' use org\majkel\dbase\Builder; use org\majkel\dbase\Format; use org\majkel\dbase\Field; $table = Builder::fromFile('source.dbf') ->setFormatType(Format::DBASE3) ->addField(Field::create(Field::TYPE_NUMERIC)->setName('newField1')) ->build('destination.dbf'); for ($i = 1; $i <= 3; ++$i) { $table->insert([ 'oldField1' => "Str $i", 'oldField2' => false, 'newField1' => $i, ]); }
Filters
Although values are automatically converted based on column type sometimes it is necessary to perform additional processing. To achieve that you can add filters on columns.
Using filters
require_once 'vendor/autoload.php' use org\majkel\dbase\Builder; use org\majkel\dbase\filter\TrimFilter; use your\CurrencyFilter; $dbf = Table::fromFile('some/table.dbf'); $dbf->getHeader()->getField('price') ->addFilter(new TrimFilter()) ->addFilter(new CurrencyFilter(',', '.')); foreach ($dbf as $record) { // ... }
Filters are applied during loading in the order they are defined. During serialization filters are applied in reversed order.
Writing custom filter
require_once 'vendor/autoload.php' use org\majkel\dbase\FilterInterface; use org\majkel\dbase\Field; class CurrencyFilter extends FilterInterface { /** @var string */ private $inputDot; /** @var string */ private $outputDot; /** * @param string $inputDot * @param string $outputDot */ public function __construct($inputDot, $outputDot) { $this->inputDot = $inputDot; $this->outputDot = $outputDot; } /** * From table value to PHP value * * @param mixed $value * @return mixed */ public function toValue($value) { return str_replace($this->inputDot, $this->outputDot, $value); } /** * From PHP value to table value * * @param mixed $value * @return mixed */ public function fromValue($value) { return str_replace($this->outputDot, $this->inputDot, $value); } /** * Filter can be applied on string like columns * * @param integer $type * @return boolean */ public function supportsType($type) { return in_aray($type, [Field::TYPE_CHARACTER, Field::TYPE_MEMO]); } }
org.majkel/dbase 适用场景与选型建议
org.majkel/dbase 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 103.36k 次下载、GitHub Stars 达 33, 最近一次更新时间为 2015 年 09 月 14 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「dbase」 「dbf」 「xbase」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 org.majkel/dbase 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 org.majkel/dbase 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 org.majkel/dbase 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
A PHP library to parse ESRI Shape files
A simple parser for *.dbf files using PHP
Package for reading DBASE-files (FoxPro) with/without MEMO-fields
A simple parser for *.dbf, *.fpt files using PHP
PHP library to read and write ESRI Shapefiles, compatible with WKT and GeoJSON
Package for converting DBASE-files to MySQL
统计信息
- 总下载量: 103.36k
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 33
- 点击次数: 32
- 依赖项目数: 1
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2015-09-14