claude-code-system-prompts/system-prompts/data-claude-api-reference-php.md
2026-03-17 17:30:45 -06:00

247 lines
7.1 KiB
Markdown

<!--
name: 'Data: Claude API reference — PHP'
description: PHP SDK reference
ccVersion: 2.1.78
-->
# Claude API — PHP
> **Note:** The PHP SDK is the official Anthropic SDK for PHP. Tool runner and Agent SDK are not available. Bedrock, Vertex AI, and Foundry clients are supported.
## Installation
\`\`\`bash
composer require "anthropic-ai/sdk"
\`\`\`
## Client Initialization
\`\`\`php
use Anthropic\\Client;
// Using API key from environment variable
$client = new Client(apiKey: getenv("ANTHROPIC_API_KEY"));
\`\`\`
### Amazon Bedrock
\`\`\`php
use Anthropic\\Bedrock;
// Constructor is private — use the static factory. Reads AWS credentials from env.
$client = Bedrock\\Client::fromEnvironment(region: 'us-east-1');
\`\`\`
### Google Vertex AI
\`\`\`php
use Anthropic\\Vertex;
// Constructor is private. Parameter is \`location\`, not \`region\`.
$client = Vertex\\Client::fromEnvironment(
location: 'us-east5',
projectId: 'my-project-id',
);
\`\`\`
### Anthropic Foundry
\`\`\`php
use Anthropic\\Foundry;
// Constructor is private. baseUrl or resource is required.
$client = Foundry\\Client::withCredentials(
authToken: getenv('ANTHROPIC_FOUNDRY_AUTH_TOKEN'),
baseUrl: 'https://<resource>.services.ai.azure.com/anthropic',
);
\`\`\`
---
## Basic Message Request
\`\`\`php
$message = $client->messages->create(
model: '{{OPUS_ID}}',
maxTokens: 16000,
messages: [
['role' => 'user', 'content' => 'What is the capital of France?'],
],
);
// content is an array of polymorphic blocks (TextBlock, ToolUseBlock,
// ThinkingBlock). Accessing ->text on content[0] without checking the block
// type will throw if the first block is not a TextBlock (e.g., when extended
// thinking is enabled and a ThinkingBlock comes first). Always guard:
foreach ($message->content as $block) {
if ($block->type === 'text') {
echo $block->text;
}
}
\`\`\`
If you only want the first text block:
\`\`\`php
foreach ($message->content as $block) {
if ($block->type === 'text') {
echo $block->text;
break;
}
}
\`\`\`
---
## Streaming
> **Requires SDK v0.5.0+.** v0.4.0 and earlier used a single \`$params\` array; calling with named parameters throws \`Unknown named parameter $model\`. Upgrade: \`composer require "anthropic-ai/sdk:^0.6"\`
\`\`\`php
use Anthropic\\Messages\\RawContentBlockDeltaEvent;
use Anthropic\\Messages\\TextDelta;
$stream = $client->messages->createStream(
model: '{{OPUS_ID}}',
maxTokens: 64000,
messages: [
['role' => 'user', 'content' => 'Write a haiku'],
],
);
foreach ($stream as $event) {
if ($event instanceof RawContentBlockDeltaEvent && $event->delta instanceof TextDelta) {
echo $event->delta->text;
}
}
\`\`\`
---
## Tool Use (Manual Loop)
Tools are passed as arrays. **The SDK uses camelCase keys** (\`inputSchema\`, \`toolUseID\`, \`stopReason\`) and auto-maps to the API's snake_case on the wire — since v0.5.0. See [shared tool use concepts](../shared/tool-use-concepts.md) for the loop pattern.
\`\`\`php
use Anthropic\\Messages\\ToolUseBlock;
$tools = [
[
'name' => 'get_weather',
'description' => 'Get the current weather in a given location',
'inputSchema' => [ // camelCase, not input_schema
'type' => 'object',
'properties' => [
'location' => ['type' => 'string', 'description' => 'City and state'],
],
'required' => ['location'],
],
],
];
$messages = [['role' => 'user', 'content' => 'What is the weather in SF?']];
$response = $client->messages->create(
model: '{{OPUS_ID}}',
maxTokens: 16000,
tools: $tools,
messages: $messages,
);
while ($response->stopReason === 'tool_use') { // camelCase property
$toolResults = [];
foreach ($response->content as $block) {
if ($block instanceof ToolUseBlock) {
// $block->name : string — tool name to dispatch on
// $block->input : array<string,mixed> — parsed JSON input
// $block->id : string — pass back as toolUseID
$result = executeYourTool($block->name, $block->input);
$toolResults[] = [
'type' => 'tool_result',
'toolUseID' => $block->id, // camelCase, not tool_use_id
'content' => $result,
];
}
}
// Append assistant turn + user turn with tool results
$messages[] = ['role' => 'assistant', 'content' => $response->content];
$messages[] = ['role' => 'user', 'content' => $toolResults];
$response = $client->messages->create(
model: '{{OPUS_ID}}',
maxTokens: 16000,
tools: $tools,
messages: $messages,
);
}
// Final text response
foreach ($response->content as $block) {
if ($block->type === 'text') {
echo $block->text;
}
}
\`\`\`
\`$block->type === 'tool_use'\` also works; \`instanceof ToolUseBlock\` narrows for PHPStan.
---
## Extended Thinking
**Adaptive thinking is the recommended mode for Claude 4.6+ models.** Claude decides dynamically when and how much to think.
\`\`\`php
use Anthropic\\Messages\\ThinkingBlock;
$message = $client->messages->create(
model: '{{OPUS_ID}}',
maxTokens: 16000,
thinking: ['type' => 'adaptive'],
messages: [
['role' => 'user', 'content' => 'Solve: 27 * 453'],
],
);
// ThinkingBlock(s) precede TextBlock in content
foreach ($message->content as $block) {
if ($block instanceof ThinkingBlock) {
echo "Thinking:\\n{$block->thinking}\\n\\n";
// $block->signature is an opaque string — preserve verbatim if
// passing thinking blocks back in multi-turn conversations
} elseif ($block->type === 'text') {
echo "Answer: {$block->text}\\n";
}
}
\`\`\`
> **Deprecated:** \`['type' => 'enabled', 'budgetTokens' => N]\` (fixed-budget extended thinking) still works on Claude 4.6 but is deprecated. Use adaptive thinking above.
\`$block->type === 'thinking'\` also works for the check; \`instanceof\` narrows for PHPStan.
---
## Beta Features & Server-Side Tools
**\`betas:\` is NOT a param on \`$client->messages->create()\`** — it only exists on the beta namespace. Use it for features that need an explicit opt-in header:
\`\`\`php
use Anthropic\\Beta\\Messages\\BetaRequestMCPServerURLDefinition;
$response = $client->beta->messages->create(
model: '{{OPUS_ID}}',
maxTokens: 16000,
mcpServers: [
BetaRequestMCPServerURLDefinition::with(
name: 'my-server',
url: 'https://example.com/mcp',
),
],
betas: ['mcp-client-2025-11-20'], // only valid on ->beta->messages
messages: [['role' => 'user', 'content' => 'Use the MCP tools']],
);
\`\`\`
**Server-side tools** (bash, web_search, text_editor, code_execution) are GA and work on both paths — \`Anthropic\\Messages\\ToolBash20250124\` / \`WebSearchTool20260209\` / \`ToolTextEditor20250728\` / \`CodeExecutionTool20260120\` for non-beta, \`Anthropic\\Beta\\Messages\\BetaToolBash20250124\` / \`BetaWebSearchTool20260209\` / \`BetaToolTextEditor20250728\` / \`BetaCodeExecutionTool20260120\` for beta. No \`betas:\` header needed for these.