php可以通过curl调用tensorfold的openai兼容chat/completions接口,并读取choices中的文本结果。先在同一主机或受控网络启动模型服务,设置服务密钥,再让php从环境变量读取;兼容路径不代表支持所有openai能力,本文只使用单条非流式文本请求。
服务端配置受限密钥文件
umask 077 openssl rand -hex 24 > tensorfold-key tensorfold serve mlx-community/Qwen3.5-2B-MLX-4bit --name local-model --context 8192 --api-key-file tensorfold-key
密钥文件应为0600权限,官方说明可被其他用户读取时启动会拒绝。不要把真实密钥写进PHP文件或版本库;通过部署环境把同一个值设置为TENSORFOLD_API_KEY。服务有密钥后,/health只返回简化状态,并不会证明已认证的模型请求一定通过。

TensorFold官方文档说明密钥文件权限与Bearer认证
发送请求并处理HTTP与解析错误
<?php
$key = getenv('TENSORFOLD_API_KEY');
if (!$key) { throw new RuntimeException('Missing TENSORFOLD_API_KEY'); }
$ch = curl_init('http://127.0.0.1:8080/v1/chat/completions');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CONNECTTIMEOUT => 5,
CURLOPT_TIMEOUT => 90,
CURLOPT_HTTPHEADER => ['Content-Type: application/json', 'Authorization: Bearer ' . $key],
CURLOPT_POSTFIELDS => json_encode([
'model' => 'local-model',
'messages' => [['role' => 'user', 'content' => '用中文说明HTTP超时的含义。']],
'max_tokens' => 256,
'stream' => false,
], JSON_THROW_ON_ERROR),
]);
$raw = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$error = curl_error($ch);
curl_close($ch);
if ($raw === false) { throw new RuntimeException($error); }
if ($status < 200 || $status >= 300) { throw new RuntimeException('HTTP ' . $status); }
$data = json_decode($raw, true, 512, JSON_THROW_ON_ERROR);
$text = $data['choices'][0]['message']['content'] ?? null;
if (!is_string($text)) { throw new RuntimeException('No text response'); }
echo $text;
官方参数表列出messages、max_tokens和stream等字段
核对模型、上下文与运行位置
模型名对应服务启动时的--name。输入加显式回复预算超过窗口会被拒绝,应先减少上下文或合理调整服务容量;不要自动去掉预算后无限生成。当前接口文档限定文本输入输出,不把图片或音频字段直接搬进这一调用。
127.0.0.1指PHP进程所在环境;PHP运行在容器时,它通常不等于Mac主机的服务。跨主机部署应另行规划认证、TLS与网络访问边界,不能把示例改成公网监听就视为完成部署。



















