Appearance
MongoDB Long 类型详解
本知识点承接《MongoDB数据类型概述》,后续延伸至《MongoDB数值计算》,建议学习顺序:MongoDB基础→数据类型概述→本知识点→数值计算
1. 概述
在MongoDB数据库中,Long类型(也称为Int64)是一种BSON数值类型(BSON type 0x12),用于存储64位有符号整数。Long类型的取值范围是-9,223,372,036,854,775,808到9,223,372,036,854,775,807(即-2^63到2^63-1),适合存储大范围的整数值。
在PHP中,我们使用MongoDB\BSON\Int64类来显式创建Long类型的值。PHP的整数类型在64位平台上会自动映射到Long类型,但在32位平台上需要显式使用Int64类来处理大整数。Long类型的主要应用场景包括:存储大ID、时间戳(毫秒级)、大计数器、文件大小、金额(分)等需要大范围整数的场景。
理解Long类型有助于开发者正确处理大整数数据,避免32位整数的溢出问题,确保数据的准确性和完整性。
2. 基本概念
2.1 语法
MongoDB Long类型在PHP中使用MongoDB\BSON\Int64类表示,其基本语法如下:
php
use MongoDB\BSON\Int64;
// 创建Int64对象
$int64 = new Int64(int|string $value);
// 参数说明:
// $value: 整数值或字符串表示的整数Long取值范围:
| 边界 | 值 | 说明 |
|---|---|---|
| 最小值 | -9,223,372,036,854,775,808 | -2^63 |
| 最大值 | 9,223,372,036,854,775,807 | 2^63-1 |
| 存储 | 8字节 | 64位有符号整数 |
MongoDB数值类型对比:
| 类型 | BSON码 | 范围 | 存储 |
|---|---|---|---|
| Int32 | 0x10 | ±2.1×10^9 | 4字节 |
| Int64/Long | 0x12 | ±9.2×10^18 | 8字节 |
| Double | 0x01 | ±1.8×10^308 | 8字节 |
| Decimal128 | 0x13 | 34位精度 | 16字节 |
2.2 语义
Long类型在MongoDB中的语义主要体现在以下几个方面:
存储语义:
- 作为64位有符号整数存储
- 类型码为0x12
- 占用8字节存储空间
比较语义:
- 与其他数值类型进行数值比较
- Long与Int32、Double比较时按数值比较
- 在排序中按数值大小排序
类型转换语义:
- PHP 64位整数自动映射为Long
- PHP 32位整数需要显式使用Int64
- 字符串形式的整数可转换为Int64
php
<?php
require_once __DIR__ . '/vendor/autoload.php';
use MongoDB\BSON\Int64;
use MongoDB\Client;
echo "=== Long基本语义 ===\n\n";
// 1. 创建Int64对象
echo "1. 创建Int64对象:\n";
$int64 = new Int64(9223372036854775807);
echo " 类型: " . get_class($int64) . "\n";
echo " 值: " . $int64 . "\n";
// 2. JSON序列化
echo "\n2. JSON序列化:\n";
echo " " . json_encode(['num' => $int64], JSON_PRETTY_PRINT) . "\n";
// 3. 取值范围
echo "\n3. 取值范围:\n";
echo " 最小值: " . new Int64("-9223372036854775808") . "\n";
echo " 最大值: " . new Int64("9223372036854775807") . "\n";
// 4. 类型比较
echo "\n4. 类型比较演示:\n";
$client = new Client('mongodb://localhost:27017');
$collection = $client->test->long_demo;
$collection->drop();
$collection->insertMany([
['name' => 'Long', 'value' => new Int64(100)],
['name' => 'PHP Int', 'value' => 100],
['name' => 'Double', 'value' => 100.0]
]);
$results = $collection->find(['value' => 100]);
echo " 查询 value = 100 的结果:\n";
foreach ($results as $doc) {
echo " - {$doc->name}\n";
}
?>输出结果:
=== Long基本语义 ===
1. 创建Int64对象:
类型: MongoDB\BSON\Int64
值: 9223372036854775807
2. JSON序列化:
{
"num": {
"$numberLong": "9223372036854775807"
}
}
3. 取值范围:
最小值: -9223372036854775808
最大值: 9223372036854775807
4. 类型比较演示:
查询 value = 100 的结果:
- Long
- PHP Int
- Double2.3 存储结构
Long类型在BSON中的存储结构:
┌─────────────────────────────────────────────────────┐
│ BSON Long (Int64) │
├─────────────────────────────────────────────────────┤
│ Type (1 byte): 0x12 │
│ Name (cstring): 字段名 │
│ Value (int64): 64位有符号整数 │
│ └─ 8 bytes, little-endian │
└─────────────────────────────────────────────────────┘3. 基础用法
3.1 创建Long对象
php
<?php
require_once __DIR__ . '/vendor/autoload.php';
use MongoDB\BSON\Int64;
echo "=== 创建Long对象 ===\n\n";
// 方式1:直接实例化
$int64_1 = new Int64(42);
echo "1. 直接实例化: " . $int64_1 . "\n";
// 方式2:从字符串创建(推荐用于大整数)
$int64_2 = new Int64("9223372036854775807");
echo "2. 从字符串创建: " . $int64_2 . "\n";
// 方式3:负数
$int64_3 = new Int64(-100);
echo "3. 负数: " . $int64_3 . "\n";
// 方式4:边界值
$int64_min = new Int64("-9223372036854775808");
$int64_max = new Int64("9223372036854775807");
echo "4. 边界值: min={$int64_min}, max={$int64_max}\n";
// 获取值
echo "\n获取值:\n";
echo " __toString(): " . $int64_1->__toString() . "\n";
echo " (string)转换: " . (string)$int64_1 . "\n";
?>3.2 Long与PHP整数的关系
php
<?php
require_once __DIR__ . '/vendor/autoload.php';
use MongoDB\BSON\Int64;
use MongoDB\Client;
echo "=== Long与PHP整数的关系 ===\n\n";
echo "PHP平台信息:\n";
echo " PHP_INT_SIZE: " . PHP_INT_SIZE . " 字节\n";
echo " PHP_INT_MAX: " . PHP_INT_MAX . "\n";
$client = new Client('mongodb://localhost:27017');
$collection = $client->test->long_php;
$collection->drop();
// PHP整数自动映射
$collection->insertMany([
['name' => 'small_int', 'value' => 100],
['name' => 'large_int', 'value' => 3000000000],
['name' => 'explicit_int64', 'value' => new Int64(100)],
['name' => 'very_large', 'value' => new Int64("9223372036854775800")]
]);
echo "\n存储结果分析:\n";
$results = $collection->find([]);
foreach ($results as $doc) {
$type = gettype($doc->value);
$class = is_object($doc->value) ? get_class($doc->value) : 'native';
echo " {$doc->name}: {$doc->value} (PHP类型: {$type}, 类: {$class})\n";
}
?>3.3 Long在查询中的使用
php
<?php
require_once __DIR__ . '/vendor/autoload.php';
use MongoDB\BSON\Int64;
use MongoDB\Client;
echo "=== Long在查询中的使用 ===\n\n";
$client = new Client('mongodb://localhost:27017');
$collection = $client->test->long_query;
$collection->drop();
$collection->insertMany([
['name' => 'Item A', 'quantity' => new Int64(10)],
['name' => 'Item B', 'quantity' => new Int64(50)],
['name' => 'Item C', 'quantity' => new Int64(100)],
['name' => 'Item D', 'quantity' => new Int64(200)]
]);
// 精确查询
echo "精确查询 quantity = 50:\n";
$results = $collection->find(['quantity' => new Int64(50)]);
foreach ($results as $doc) {
echo " - {$doc->name}: {$doc->quantity}\n";
}
// 范围查询
echo "\n范围查询 quantity > 50:\n";
$results = $collection->find(['quantity' => ['$gt' => new Int64(50)]]);
foreach ($results as $doc) {
echo " - {$doc->name}: {$doc->quantity}\n";
}
// 排序
echo "\n排序查询(降序):\n";
$results = $collection->find([], ['sort' => ['quantity' => -1]]);
foreach ($results as $doc) {
echo " - {$doc->name}: {$doc->quantity}\n";
}
?>4. 进阶用法
4.1 大ID生成器
php
<?php
require_once __DIR__ . '/vendor/autoload.php';
use MongoDB\BSON\Int64;
use MongoDB\Client;
echo "=== 大ID生成器 ===\n\n";
class LargeIdGenerator
{
private $collection;
public function __construct($collection)
{
$this->collection = $collection;
}
public function nextId(): string
{
$result = $this->collection->findOneAndUpdate(
['_id' => 'counter'],
['$inc' => ['value' => new Int64(1)]],
[
'returnDocument' => MongoDB\Operation\FindOneAndUpdate::RETURN_DOCUMENT_AFTER,
'upsert' => true
]
);
return (string)$result->value;
}
public function batchIds(int $count): array
{
$ids = [];
for ($i = 0; $i < $count; $i++) {
$ids[] = $this->nextId();
}
return $ids;
}
}
$client = new Client('mongodb://localhost:27017');
$collection = $client->test->id_generator;
$collection->drop();
$generator = new LargeIdGenerator($collection);
echo "生成ID:\n";
for ($i = 1; $i <= 5; $i++) {
$id = $generator->nextId();
echo " ID {$i}: {$id}\n";
}
?>4.2 时间戳存储
php
<?php
require_once __DIR__ . '/vendor/autoload.php';
use MongoDB\BSON\Int64;
use MongoDB\Client;
echo "=== 时间戳存储 ===\n\n";
class TimestampStorage
{
private $collection;
public function __construct($collection)
{
$this->collection = $collection;
}
public function storeEvent(string $event): void
{
$microtime = microtime(true);
$milliseconds = (int)($microtime * 1000);
$this->collection->insertOne([
'event' => $event,
'timestamp' => new Int64($milliseconds),
'created' => new MongoDB\BSON\UTCDateTime()
]);
}
public function getEventsAfter(string $timestamp): array
{
return $this->collection->find([
'timestamp' => ['$gte' => new Int64($timestamp)]
])->toArray();
}
public function getLatestEvent(): ?array
{
$result = $this->collection->findOne(
[],
['sort' => ['timestamp' => -1]]
);
return $result ? (array)$result : null;
}
}
$client = new Client('mongodb://localhost:27017');
$collection = $client->test->event_timestamps;
$collection->drop();
$storage = new TimestampStorage($collection);
$storage->storeEvent('Event A');
$storage->storeEvent('Event B');
$storage->storeEvent('Event C');
echo "存储的事件:\n";
$events = $collection->find([], ['sort' => ['timestamp' => 1]]);
foreach ($events as $event) {
$ts = (string)$event->timestamp;
echo " - {$event->event}: {$ts} ms\n";
}
?>4.3 金额存储(分)
php
<?php
require_once __DIR__ . '/vendor/autoload.php';
use MongoDB\BSON\Int64;
use MongoDB\Client;
echo "=== 金额存储(分) ===\n\n";
class MoneyStorage
{
private $collection;
public function __construct($collection)
{
$this->collection = $collection;
}
public function deposit(string $account, int $cents): void
{
$this->collection->updateOne(
['account' => $account],
['$inc' => ['balance' => new Int64($cents)]],
['upsert' => true]
);
}
public function withdraw(string $account, int $cents): bool
{
$result = $this->collection->findOneAndUpdate(
['account' => $account, 'balance' => ['$gte' => new Int64($cents)]],
['$inc' => ['balance' => new Int64(-$cents)]]
);
return $result !== null;
}
public function getBalance(string $account): string
{
$result = $this->collection->findOne(['account' => $account]);
if (!$result) return '0.00';
$cents = (int)(string)$result->balance;
$dollars = $cents / 100;
return number_format($dollars, 2);
}
public function transfer(string $from, string $to, int $cents): bool
{
$fromBalance = $this->collection->findOne(['account' => $from]);
if (!$fromBalance || (int)(string)$fromBalance->balance < $cents) {
return false;
}
$this->withdraw($from, $cents);
$this->deposit($to, $cents);
return true;
}
}
$client = new Client('mongodb://localhost:27017');
$collection = $client->test->money_storage;
$collection->drop();
$money = new MoneyStorage($collection);
$money->deposit('user1', 10000);
$money->deposit('user2', 5000);
echo "初始余额:\n";
echo " user1: $" . $money->getBalance('user1') . "\n";
echo " user2: $" . $money->getBalance('user2') . "\n";
$money->transfer('user1', 'user2', 2000);
echo "\n转账后余额:\n";
echo " user1: $" . $money->getBalance('user1') . "\n";
echo " user2: $" . $money->getBalance('user2') . "\n";
?>5. 实际应用场景
5.1 大计数器
php
<?php
require_once __DIR__ . '/vendor/autoload.php';
use MongoDB\BSON\Int64;
use MongoDB\Client;
echo "=== 大计数器 ===\n\n";
class LargeCounter
{
private $collection;
public function __construct($collection)
{
$this->collection = $collection;
}
public function increment(string $name, int $delta = 1): string
{
$result = $this->collection->findOneAndUpdate(
['name' => $name],
[
'$inc' => ['value' => new Int64($delta)],
'$set' => ['updated' => new MongoDB\BSON\UTCDateTime()]
],
[
'returnDocument' => MongoDB\Operation\FindOneAndUpdate::RETURN_DOCUMENT_AFTER,
'upsert' => true
]
);
return (string)$result->value;
}
public function get(string $name): string
{
$result = $this->collection->findOne(['name' => $name]);
return $result ? (string)$result->value : '0';
}
public function reset(string $name): void
{
$this->collection->updateOne(
['name' => $name],
['$set' => ['value' => new Int64(0)]]
);
}
}
$client = new Client('mongodb://localhost:27017');
$collection = $client->test->large_counters;
$collection->drop();
$counter = new LargeCounter($collection);
echo "计数器操作:\n";
echo " 初始: " . $counter->increment('total_requests') . "\n";
echo " 增加100: " . $counter->increment('total_requests', 100) . "\n";
echo " 增加1000: " . $counter->increment('total_requests', 1000) . "\n";
echo " 当前值: " . $counter->get('total_requests') . "\n";
?>5.2 文件大小统计
php
<?php
require_once __DIR__ . '/vendor/autoload.php';
use MongoDB\BSON\Int64;
use MongoDB\Client;
echo "=== 文件大小统计 ===\n\n";
class FileSizeTracker
{
private $collection;
public function __construct($collection)
{
$this->collection = $collection;
}
public function addFile(string $path, int $bytes): void
{
$this->collection->insertOne([
'path' => $path,
'size' => new Int64($bytes),
'added' => new MongoDB\BSON\UTCDateTime()
]);
}
public function getTotalSize(): string
{
$pipeline = [
['$group' => ['_id' => null, 'total' => ['$sum' => '$size']]]
];
$result = $this->collection->aggregate($pipeline)->toArray();
if (empty($result)) return '0';
return (string)$result[0]->total;
}
public function formatBytes(int $bytes): string
{
$units = ['B', 'KB', 'MB', 'GB', 'TB'];
$i = 0;
while ($bytes >= 1024 && $i < count($units) - 1) {
$bytes /= 1024;
$i++;
}
return round($bytes, 2) . ' ' . $units[$i];
}
}
$client = new Client('mongodb://localhost:27017');
$collection = $client->test->file_sizes;
$collection->drop();
$tracker = new FileSizeTracker($collection);
$tracker->addFile('/path/file1.txt', 1024);
$tracker->addFile('/path/file2.txt', 1048576);
$tracker->addFile('/path/file3.txt', 1073741824);
echo "文件统计:\n";
$total = $tracker->getTotalSize();
echo " 总大小: " . $tracker->formatBytes((int)$total) . "\n";
?>5.3 分布式ID生成
php
<?php
require_once __DIR__ . '/vendor/autoload.php';
use MongoDB\BSON\Int64;
use MongoDB\Client;
echo "=== 分布式ID生成 ===\n\n";
class DistributedIdGenerator
{
private $collection;
private $nodeId;
public function __construct($collection, int $nodeId)
{
$this->collection = $collection;
$this->nodeId = $nodeId;
}
public function generate(): string
{
$timestamp = (int)(microtime(true) * 1000);
$sequence = $this->getSequence($timestamp);
$id = ($timestamp << 22) | ($this->nodeId << 12) | $sequence;
return (string)new Int64($id);
}
private function getSequence(int $timestamp): int
{
$result = $this->collection->findOneAndUpdate(
['_id' => $this->nodeId],
[
'$inc' => ['sequence' => new Int64(1)],
'$set' => ['timestamp' => new Int64($timestamp)]
],
[
'returnDocument' => MongoDB\Operation\FindOneAndUpdate::RETURN_DOCUMENT_AFTER,
'upsert' => true
]
);
if ((string)$result->timestamp != (string)$timestamp) {
$this->collection->updateOne(
['_id' => $this->nodeId],
['$set' => ['sequence' => new Int64(0)]]
);
return 0;
}
return (int)(string)$result->sequence % 4096;
}
}
$client = new Client('mongodb://localhost:27017');
$collection = $client->test->distributed_ids;
$collection->drop();
$generator = new DistributedIdGenerator($collection, 1);
echo "生成分布式ID:\n";
for ($i = 1; $i <= 5; $i++) {
$id = $generator->generate();
echo " ID {$i}: {$id}\n";
}
?>6. 性能优化
6.1 索引与Long
php
<?php
require_once __DIR__ . '/vendor/autoload.php';
use MongoDB\BSON\Int64;
use MongoDB\Client;
echo "=== 索引与Long ===\n\n";
$client = new Client('mongodb://localhost:27017');
$collection = $client->test->long_index;
$collection->drop();
// 创建索引
$collection->createIndex(['user_id' => 1]);
$collection->createIndex(['score' => -1]);
// 插入数据
$data = [];
for ($i = 1; $i <= 10000; $i++) {
$data[] = [
'user_id' => new Int64($i),
'score' => new Int64(rand(0, 1000000))
];
}
$collection->insertMany($data);
echo "插入10000条记录\n";
// 使用索引查询
echo "\n索引查询测试:\n";
$startTime = microtime(true);
$result = $collection->findOne(['user_id' => new Int64(5000)]);
$endTime = microtime(true);
echo " 查询user_id=5000: " . round(($endTime - $startTime) * 1000, 2) . " ms\n";
// 范围查询
$startTime = microtime(true);
$results = $collection->find(['score' => ['$gt' => new Int64(900000)]])->toArray();
$endTime = microtime(true);
echo " 查询score>900000: " . count($results) . " 条, " . round(($endTime - $startTime) * 1000, 2) . " ms\n";
?>7. 安全注意事项
7.1 溢出检测
php
<?php
require_once __DIR__ . '/vendor/autoload.php';
use MongoDB\BSON\Int64;
echo "=== 溢出检测 ===\n\n";
class SafeInt64
{
const MIN = "-9223372036854775808";
const MAX = "9223372036854775807";
public static function create($value): Int64
{
$strValue = (string)$value;
if (bccomp($strValue, self::MIN) < 0 || bccomp($strValue, self::MAX) > 0) {
throw new OverflowException("Value {$strValue} is out of Int64 range");
}
return new Int64($strValue);
}
public static function safeAdd(Int64 $a, Int64 $b): Int64
{
$result = bcadd((string)$a, (string)$b);
return self::create($result);
}
public static function safeMultiply(Int64 $a, Int64 $b): Int64
{
$result = bcmul((string)$a, (string)$b);
return self::create($result);
}
}
// 测试
echo "安全创建:\n";
try {
$int64 = SafeInt64::create("9223372036854775807");
echo " 创建成功: {$int64}\n";
$overflow = SafeInt64::create("9223372036854775808");
} catch (OverflowException $e) {
echo " 溢出错误: " . $e->getMessage() . "\n";
}
?>8. 常见问题与解决方案
问题1:Long和PHP整数有什么区别?
问题描述:PHP整数和MongoDB Long有什么不同?
回答内容:
PHP整数根据平台可能是32位或64位,而Long固定为64位。
php
<?php
use MongoDB\BSON\Int64;
echo "=== Long vs PHP整数 ===\n\n";
echo "PHP整数大小: " . PHP_INT_SIZE . " 字节\n";
echo "PHP整数最大值: " . PHP_INT_MAX . "\n";
echo "\nLong范围:\n";
echo " 最小值: -9223372036854775808\n";
echo " 最大值: 9223372036854775807\n";
echo "\n区别:\n";
echo " 1. Long固定64位,PHP整数依赖平台\n";
echo " 2. Long可以存储更大的整数\n";
echo " 3. 在32位PHP上需要显式使用Int64\n";
?>问题2:什么时候应该使用Long?
问题描述:什么场景下应该显式使用Long类型?
回答内容:
当需要存储大整数、确保64位精度或与32位PHP平台兼容时使用Long。
php
<?php
use MongoDB\BSON\Int64;
echo "=== Long使用场景 ===\n\n";
echo "推荐使用Long:\n";
echo " 1. 存储大ID、时间戳等大整数\n";
echo " 2. 需要确保64位精度的场景\n";
echo " 3. 32位PHP平台处理大整数\n";
echo " 4. 金额(分)、文件大小等\n";
echo "\n示例:\n";
echo " \$id = new Int64('9223372036854775807');\n";
echo " \$timestamp = new Int64(microtime(true) * 1000);\n";
echo " \$cents = new Int64(10000);\n";
?>问题3:Long溢出会怎样?
问题描述:超出Long范围的值会发生什么?
回答内容:
超出范围会抛出异常,需要使用Decimal128或字符串存储。
php
<?php
use MongoDB\BSON\Int64;
echo "=== Long溢出处理 ===\n\n";
// 正常范围
echo "正常范围:\n";
$normal = new Int64("9223372036854775807");
echo " 最大值: {$normal}\n";
// 超出范围
echo "\n超出范围:\n";
try {
$overflow = new Int64("9223372036854775808");
} catch (InvalidArgumentException $e) {
echo " 错误: " . $e->getMessage() . "\n";
}
echo "\n解决方案:\n";
echo " 1. 使用Decimal128存储超大数值\n";
echo " 2. 使用字符串存储精确数值\n";
echo " 3. 在应用层进行范围检查\n";
?>9. 实战练习
练习1:实现大计数器
练习描述:创建一个支持大计数的计数器系统。
解题思路:
- 使用Int64存储计数值
- 提供安全的增减操作
- 记录操作历史
参考代码:
php
<?php
use MongoDB\BSON\Int64;
use MongoDB\Client;
class LargeCounterSystem
{
private $collection;
public function __construct($collection)
{
$this->collection = $collection;
}
public function increment(string $name, int $delta = 1): string
{
$result = $this->collection->findOneAndUpdate(
['name' => $name],
['$inc' => ['value' => new Int64($delta)]],
['upsert' => true, 'returnDocument' => MongoDB\Operation\FindOneAndUpdate::RETURN_DOCUMENT_AFTER]
);
return (string)$result->value;
}
public function get(string $name): string
{
$result = $this->collection->findOne(['name' => $name]);
return $result ? (string)$result->value : '0';
}
}
echo "=== 大计数器系统 ===\n\n";
$client = new Client('mongodb://localhost:27017');
$collection = $client->test->large_counter_system;
$collection->drop();
$counter = new LargeCounterSystem($collection);
echo "计数: " . $counter->increment('total') . "\n";
echo "计数: " . $counter->increment('total', 1000000000) . "\n";
?>练习2:实现分布式ID生成器
练习描述:创建一个分布式唯一ID生成器。
解题思路:
- 使用时间戳、节点ID和序列号
- 确保ID唯一性
- 使用Int64存储
参考代码:
php
<?php
use MongoDB\BSON\Int64;
use MongoDB\Client;
class SnowflakeIdGenerator
{
private $collection;
private $nodeId;
public function __construct($collection, int $nodeId)
{
$this->collection = $collection;
$this->nodeId = $nodeId;
}
public function generate(): string
{
$timestamp = (int)(microtime(true) * 1000);
$sequence = $this->getNextSequence($timestamp);
$id = ($timestamp << 22) | ($this->nodeId << 12) | $sequence;
return (string)new Int64($id);
}
private function getNextSequence(int $timestamp): int
{
$result = $this->collection->findOneAndUpdate(
['_id' => $this->nodeId],
[
'$inc' => ['sequence' => new Int64(1)],
'$set' => ['last_timestamp' => new Int64($timestamp)]
],
['upsert' => true, 'returnDocument' => MongoDB\Operation\FindOneAndUpdate::RETURN_DOCUMENT_AFTER]
);
if ((string)$result->last_timestamp != (string)$timestamp) {
$this->collection->updateOne(
['_id' => $this->nodeId],
['$set' => ['sequence' => new Int64(0)]]
);
return 0;
}
return (int)(string)$result->sequence % 4096;
}
}
echo "=== Snowflake ID生成器 ===\n\n";
$client = new Client('mongodb://localhost:27017');
$collection = $client->test->snowflake_ids;
$collection->drop();
$generator = new SnowflakeIdGenerator($collection, 1);
echo "生成ID:\n";
for ($i = 1; $i <= 5; $i++) {
$id = $generator->generate();
echo " ID {$i}: {$id}\n";
}
?>10. 知识点总结
核心概念回顾
| 概念 | 说明 | 重要程度 |
|---|---|---|
| BSON类型码 | 0x12,64位有符号整数 | ⭐⭐⭐ |
| PHP类 | MongoDB\BSON\Int64 | ⭐⭐⭐ |
| 取值范围 | -2^63 到 2^63-1 | ⭐⭐⭐ |
| 存储空间 | 8字节 | ⭐⭐ |
| 比较语义 | 数值比较 | ⭐⭐ |
| 溢出处理 | 抛出异常 | ⭐⭐⭐ |
关键技能掌握
必须掌握:
- Int64对象的创建
- 理解取值范围
- 溢出检测和处理
- 与PHP整数的区别
建议掌握:
- 大ID生成
- 时间戳存储
- 金额存储(分)
- 分布式ID生成
最佳实践清单
创建Long:
php
$int64 = new Int64("9223372036854775807");安全操作:
php
if (bccomp($value, "-9223372036854775808") >= 0 && bccomp($value, "9223372036854775807") <= 0) {
$int64 = new Int64($value);
}计数器:
php
$collection->updateOne(['name' => 'counter'], ['$inc' => ['value' => new Int64(1)]]);常见错误避免
| 错误 | 正确做法 |
|---|---|
| 忽略溢出 | 添加范围检查 |
| 32位平台问题 | 使用字符串创建Int64 |
| 混用类型 | 保持类型一致 |
| 精度丢失 | 使用Int64而非Double |
11. 拓展参考资料
官方文档
PHP驱动文档
相关章节
- Integer类型:整数类型概述
- Int32类型:32位整数
- Double类型:浮点数
- Decimal128类型:高精度数值
