—— 和正文无关的内容分隔线 ——
结论先说:可以。octdec() 用于把八进制字符串 → 十进制整数,decoct() 用于把十进制整数 → 八进制字符串。两者配合即可实现双向转换。下面把用法、易错点与进阶方案一次讲清。
<span><span><span class="hljs-meta"><?php</span></span><span>
</span><span><span class="hljs-comment">// 八进制 → 十进制</span></span><span>
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-title function_ invoke__">octdec</span></span><span>(</span><span><span class="hljs-string">'17'</span></span><span>); </span><span><span class="hljs-comment">// 15</span></span><span>
</span><span><span class="hljs-keyword">echo</span></span><span> PHP_EOL;
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-title function_ invoke__">octdec</span></span><span>(</span><span><span class="hljs-string">'011'</span></span><span>); </span><span><span class="hljs-comment">// 9(字符串里的前导 0 不会改变含义,它仍按八进制解析)</span></span><span>
</span><span><span class="hljs-comment">// 十进制 → 八进制</span></span><span>
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-title function_ invoke__">decoct</span></span><span>(</span><span><span class="hljs-number">15</span></span><span>); </span><span><span class="hljs-comment">// "17"</span></span><span>
</span><span><span class="hljs-keyword">echo</span></span><span> PHP_EOL;
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-title function_ invoke__">decoct</span></span><span>(</span><span><span class="hljs-number">9</span></span><span>); </span><span><span class="hljs-comment">// "11"</span></span><span>
</span></span>
要点:
octdec(string $octal): int —— 参数是字符串,返回十进制整数。
decoct(int $decimal): string —— 参数是整数,返回八进制的字符串。
八进制只允许 0–7。传入如 8、9 或非数字字符会被忽略到第一个非法处之后,结果容易与你的预期不符。先校验再转换最稳妥。
<span><span><span class="hljs-meta"><?php</span></span><span>
</span><span><span class="hljs-function"><span class="hljs-keyword">function</span></span></span><span> </span><span><span class="hljs-title">isValidOctal</span></span><span>(</span><span><span class="hljs-params"><span class="hljs-keyword">string</span></span></span><span> </span><span><span class="hljs-variable">$s</span></span><span>): </span><span><span class="hljs-title">bool</span></span><span> {
</span><span><span class="hljs-comment">// 允许前导 0;至少一个八进制数字</span></span><span>
</span><span><span class="hljs-keyword">return</span></span><span> (</span><span><span class="hljs-keyword">bool</span></span><span>)</span><span><span class="hljs-title function_ invoke__">preg_match</span></span><span>(</span><span><span class="hljs-string">'/^[0-7]+$/'</span></span><span>, </span><span><span class="hljs-variable">$s</span></span><span>);
}
</span><span><span class="hljs-variable">$input</span></span><span> = </span><span><span class="hljs-string">'128'</span></span><span>; </span><span><span class="hljs-comment">// 非法</span></span><span>
</span><span><span class="hljs-keyword">if</span></span><span> (!</span><span><span class="hljs-title function_ invoke__">isValidOctal</span></span><span>(</span><span><span class="hljs-variable">$input</span></span><span>)) {
</span><span><span class="hljs-keyword">throw</span></span><span> </span><span><span class="hljs-keyword">new</span></span><span> </span><span><span class="hljs-built_in">InvalidArgumentException</span></span><span>(</span><span><span class="hljs-string">"不是合法的八进制数:<span class="hljs-subst">{$input}</span></span></span><span>");
}
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-title function_ invoke__">octdec</span></span><span>(</span><span><span class="hljs-variable">$input</span></span><span>);
</span></span>
字符串 "011" 只是文本,octdec("011") 会按八进制解析为 9。
PHP 代码里的整数字面量 若写成 011,这是八进制字面量(等于十进制 9)。建议避免在源码中使用前导 0 的整数字面量,以免阅读混淆;需要八进制时更清晰的做法是使用字符串配合 octdec()。
decoct() 的参数是整数。对负数时,它会按实现平台的位宽(通常 64 位)以二进制补码形式参与运算并给出一个看起来“很长”的八进制表示,这通常不是你要的结果。如无特别需求,请只处理非负整数。
<span><span><span class="hljs-meta"><?php</span></span><span>
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-title function_ invoke__">decoct</span></span><span>(-</span><span><span class="hljs-number">10</span></span><span>); </span><span><span class="hljs-comment">// 依平台而异,通常是很长的一串</span></span><span>
</span></span>
在 64 位 PHP 上,int 最大约为 9.22e18。decoct() 受此限制。
若需要处理超大十进制数(超过 int 范围)的转换,考虑:
使用 gmp_* (如 gmp_init + gmp_strval($n, 8));
或使用 bc/自写大数算法。
八进制→十进制时,octdec() 返回 int,同样受限;超出时请改用 gmp/bc 方案。
<span><span><span class="hljs-meta"><?php</span></span><span>
</span><span><span class="hljs-function"><span class="hljs-keyword">function</span></span></span><span> </span><span><span class="hljs-title">octalToDecimal</span></span><span>(</span><span><span class="hljs-params"><span class="hljs-keyword">string</span></span></span><span> </span><span><span class="hljs-variable">$oct</span></span><span>): </span><span><span class="hljs-title">int</span></span><span> {
</span><span><span class="hljs-keyword">if</span></span><span> (!</span><span><span class="hljs-title function_ invoke__">preg_match</span></span><span>(</span><span><span class="hljs-string">'/^[0-7]+$/'</span></span><span>, </span><span><span class="hljs-variable">$oct</span></span><span>)) {
</span><span><span class="hljs-keyword">throw</span></span><span> </span><span><span class="hljs-keyword">new</span></span><span> </span><span><span class="hljs-built_in">InvalidArgumentException</span></span><span>(</span><span><span class="hljs-string">"非法八进制:<span class="hljs-subst">$oct</span></span></span><span>");
}
</span><span><span class="hljs-keyword">return</span></span><span> </span><span><span class="hljs-title function_ invoke__">octdec</span></span><span>(</span><span><span class="hljs-variable">$oct</span></span><span>);
}
</span></span>
<span><span><span class="hljs-meta"><?php</span></span><span>
</span><span><span class="hljs-function"><span class="hljs-keyword">function</span></span></span><span> </span><span><span class="hljs-title">decimalToOctal</span></span><span>(</span><span><span class="hljs-params"><span class="hljs-keyword">int</span></span></span><span> </span><span><span class="hljs-variable">$dec</span></span><span>): </span><span><span class="hljs-title">string</span></span><span> {
</span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-variable">$dec</span></span><span> < </span><span><span class="hljs-number">0</span></span><span>) {
</span><span><span class="hljs-keyword">throw</span></span><span> </span><span><span class="hljs-keyword">new</span></span><span> </span><span><span class="hljs-built_in">InvalidArgumentException</span></span><span>(</span><span><span class="hljs-string">"只支持非负整数"</span></span><span>);
}
</span><span><span class="hljs-keyword">return</span></span><span> </span><span><span class="hljs-title function_ invoke__">decoct</span></span><span>(</span><span><span class="hljs-variable">$dec</span></span><span>);
}
</span></span>
<span><span><span class="hljs-meta"><?php</span></span><span>
</span><span><span class="hljs-function"><span class="hljs-keyword">function</span></span></span><span> </span><span><span class="hljs-title">octalToDecimalBig</span></span><span>(</span><span><span class="hljs-params"><span class="hljs-keyword">string</span></span></span><span> </span><span><span class="hljs-variable">$oct</span></span><span>): </span><span><span class="hljs-title">string</span></span><span> {
</span><span><span class="hljs-keyword">if</span></span><span> (!</span><span><span class="hljs-title function_ invoke__">preg_match</span></span><span>(</span><span><span class="hljs-string">'/^[0-7]+$/'</span></span><span>, </span><span><span class="hljs-variable">$oct</span></span><span>)) {
</span><span><span class="hljs-keyword">throw</span></span><span> </span><span><span class="hljs-keyword">new</span></span><span> </span><span><span class="hljs-built_in">InvalidArgumentException</span></span><span>(</span><span><span class="hljs-string">"非法八进制:<span class="hljs-subst">$oct</span></span></span><span>");
}
</span><span><span class="hljs-variable">$g</span></span><span> = </span><span><span class="hljs-title function_ invoke__">gmp_init</span></span><span>(</span><span><span class="hljs-variable">$oct</span></span><span>, </span><span><span class="hljs-number">8</span></span><span>);
</span><span><span class="hljs-keyword">return</span></span><span> </span><span><span class="hljs-title function_ invoke__">gmp_strval</span></span><span>(</span><span><span class="hljs-variable">$g</span></span><span>, </span><span><span class="hljs-number">10</span></span><span>); </span><span><span class="hljs-comment">// 返回十进制“字符串”</span></span><span>
}
</span><span><span class="hljs-function"><span class="hljs-keyword">function</span></span></span><span> </span><span><span class="hljs-title">decimalToOctalBig</span></span><span>(</span><span><span class="hljs-params"><span class="hljs-keyword">string</span></span></span><span> </span><span><span class="hljs-variable">$dec</span></span><span>): </span><span><span class="hljs-title">string</span></span><span> {
</span><span><span class="hljs-keyword">if</span></span><span> (!</span><span><span class="hljs-title function_ invoke__">preg_match</span></span><span>(</span><span><span class="hljs-string">'/^[0-9]+$/'</span></span><span>, </span><span><span class="hljs-variable">$dec</span></span><span>)) {
</span><span><span class="hljs-keyword">throw</span></span><span> </span><span><span class="hljs-keyword">new</span></span><span> </span><span><span class="hljs-built_in">InvalidArgumentException</span></span><span>(</span><span><span class="hljs-string">"非法十进制:<span class="hljs-subst">$dec</span></span></span><span>");
}
</span><span><span class="hljs-variable">$g</span></span><span> = </span><span><span class="hljs-title function_ invoke__">gmp_init</span></span><span>(</span><span><span class="hljs-variable">$dec</span></span><span>, </span><span><span class="hljs-number">10</span></span><span>);
</span><span><span class="hljs-keyword">return</span></span><span> </span><span><span class="hljs-title function_ invoke__">gmp_strval</span></span><span>(</span><span><span class="hljs-variable">$g</span></span><span>, </span><span><span class="hljs-number">8</span></span><span>);
}
</span></span>
提示:GMP 扩展需在环境中启用;如果不能使用 GMP,可用 bc 或纯 PHP 实现逐位进制转换。
base_convert(string $num, int $from, int $to) 也能实现进制转换,例如:
<span><span><span class="hljs-meta"><?php</span></span><span>
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-title function_ invoke__">base_convert</span></span><span>(</span><span><span class="hljs-string">'17'</span></span><span>, </span><span><span class="hljs-number">8</span></span><span>, </span><span><span class="hljs-number">10</span></span><span>); </span><span><span class="hljs-comment">// "15"</span></span><span>
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-title function_ invoke__">base_convert</span></span><span>(</span><span><span class="hljs-string">'15'</span></span><span>, </span><span><span class="hljs-number">10</span></span><span>, </span><span><span class="hljs-number">8</span></span><span>); </span><span><span class="hljs-comment">// "17"</span></span><span>
</span></span>
区别与取舍:
base_convert() 入参/出参都是字符串,更接近“文本进制转换”的语义;
octdec()/decoct() 更贴近 “八进制?十进制”的专用 API,语义明确,且 octdec() 直接返回 int,用起来顺手;
面对超大整数时,base_convert() 在部分场景会受实现与精度限制;要绝对稳妥,仍建议用 gmp/bc。
答案:可以。 用 octdec()(八进制字符串→十进制 int)与 decoct()(十进制 int→八进制字符串)即可实现双向转换。
生产实践里请注意:输入校验、负数处理、整数字面量前导 0 的歧义、以及大整数的溢出问题。需要大数支持时,选择 gmp/bc 等方案更稳健。