PHP Lesson 8: AI Integration, Real-time Systems & Cutting-Edge Architecture
PHP Lesson 8: AI Integration, Real-time Systems & Cutting-Edge Architecture
PHP Lesson 8: AI Integration, Real-time Systems & Cutting-Edge Architecture
Welcome to Lesson 8! We're now entering the frontier of PHP development with AI integration, real-time systems, and cutting-edge architectural patterns that power modern applications.
Part 1: AI & Machine Learning Integration
1.1 AI-Powered Features with OpenAI & TensorFlow
<?php
// ai/AIService.php
class AIService {
private $openAIClient;
private $tensorFlowService;
private $cache;
public function __construct() {
$this->openAIClient = new OpenAIClient(env('OPENAI_API_KEY'));
$this->tensorFlowService = new TensorFlowService();
$this->cache = new RedisCache();
}
// AI-powered content generation
public function generateProjectDescription($projectTitle, $keywords = []) {
$cacheKey = "ai_description_" . md5($projectTitle . implode('', $keywords));
return $this->cache->remember($cacheKey, 3600, function() use ($projectTitle, $keywords) {
$prompt = "Generate a professional project description for: '{$projectTitle}'";
if (!empty($keywords)) {
$prompt .= " including keywords: " . implode(', ', $keywords);
}
$response = $this->openAIClient->chat()->create([
'model' => 'gpt-4',
'messages' => [
[
'role' => 'system',
'content' => 'You are a professional project manager. Generate concise, engaging project descriptions.'
],
[
'role' => 'user',
'content' => $prompt
]
],
'max_tokens' => 200,
'temperature' => 0.7
]);
return trim($response->choices[0]->message->content);
});
}
// Smart task prioritization
public function prioritizeTasks($tasks) {
$taskData = array_map(function($task) {
return [
'title' => $task['title'],
'description' => $task['description'],
'due_date' => $task['due_date'],
'dependencies' => count($task['dependencies'] ?? []),
'estimated_hours' => $task['estimated_hours']
];
}, $tasks);
// Use ML model to predict priority scores
$priorities = $this->tensorFlowService->predictPriorities($taskData);
// Combine with business rules
return $this->applyBusinessRules($tasks, $priorities);
}
// AI-powered code review
public function analyzeCodeQuality($codeSnippet, $language = 'php') {
$response = $this->openAIClient->chat()->create([
'model' => 'gpt-4',
'messages' => [
[
'role' => 'system',
'content' => "You are an expert {$language} code reviewer. Analyze code for best practices, security issues, and performance improvements."
],
[
'role' => 'user',
'content' => "Please review this {$language} code:\n\n{$codeSnippet}"
]
],
'max_tokens' => 500
]);
return $this->parseCodeReview($response->choices[0]->message->content);
}
// Sentiment analysis for user feedback
public function analyzeSentiment($text) {
$cacheKey = "sentiment_" . md5($text);
return $this->cache->remember($cacheKey, 1800, function() use ($text) {
$response = $this->openAIClient->embeddings()->create([
'model' => 'text-embedding-ada-002',
'input' => $text
]);
$embedding = $response->data[0]->embedding;
// Use pre-trained model for sentiment classification
return $this->tensorFlowService->classifySentiment($embedding);
});
}
// AI-powered project risk assessment
public function assessProjectRisk($projectData) {
$features = $this->extractRiskFeatures($projectData);
return $this->tensorFlowService->predictRisk($features);
}
private function applyBusinessRules($tasks, $aiPriorities) {
$finalPriorities = [];
foreach ($tasks as $index => $task) {
$aiScore = $aiPriorities[$index];
$businessScore = $this->calculateBusinessPriority($task);
// Combine AI and business logic
$finalScore = ($aiScore * 0.6) + ($businessScore * 0.4);
$finalPriorities[] = [
'task' => $task,
'priority_score' => $finalScore,
'priority_level' => $this->scoreToLevel($finalScore)
];
}
// Sort by final priority score
usort($finalPriorities, function($a, $b) {
return $b['priority_score'] <=> $a['priority_score'];
});
return $finalPriorities;
}
private function calculateBusinessPriority($task) {
$score = 0;
// Urgency factors
if ($task['due_date']) {
$daysUntilDue = (strtotime($task['due_date']) - time()) / (60 * 60 * 24);
if ($daysUntilDue < 1) $score += 10;
elseif ($daysUntilDue < 3) $score += 7;
elseif ($daysUntilDue < 7) $score += 3;
}
// Importance factors
if ($task['is_blocker'] ?? false) $score += 8;
if ($task['has_dependencies'] ?? false) $score += 5;
if ($task['estimated_hours'] > 8) $score += 2;
return min($score, 10) / 10; // Normalize to 0-1
}
private function scoreToLevel($score) {
if ($score >= 0.8) return 'critical';
if ($score >= 0.6) return 'high';
if ($score >= 0.4) return 'medium';
return 'low';
}
}
// ai/TensorFlowService.php
class TensorFlowService {
private $modelPath;
private $tfServerUrl;
public function __construct() {
$this->modelPath = storage_path('models/');
$this->tfServerUrl = env('TENSORFLOW_SERVING_URL');
}
public function predictPriorities($taskData) {
$payload = [
'signature_name' => 'predict_priority',
'instances' => $this->preprocessTaskData($taskData)
];
$response = $this->callTensorFlowServer($payload);
return $this->parsePriorityPredictions($response);
}
public function classifySentiment($embedding) {
$payload = [
'signature_name' => 'classify_sentiment',
'instances' => [$embedding]
];
$response = $this->callTensorFlowServer($payload);
return $this->parseSentimentClassification($response);
}
public function predictRisk($features) {
$payload = [
'signature_name' => 'predict_risk',
'instances' => [$features]
];
$response = $this->callTensorFlowServer($payload);
return $this->parseRiskPrediction($response);
}
private function callTensorFlowServer($payload) {
$client = new GuzzleHttp\Client();
$response = $client->post($this->tfServerUrl . '/v1/models/priority_model:predict', [
'json' => $payload,
'timeout' => 10
]);
return json_decode($response->getBody(), true);
}
private function preprocessTaskData($tasks) {
return array_map(function($task) {
return [
floatval($task['estimated_hours']),
floatval($this->normalizeDate($task['due_date'])),
floatval($task['dependencies']),
floatval(strlen($task['description'] ?? '') / 100) // Normalized description length
];
}, $tasks);
}
private function normalizeDate($date) {
if (!$date) return 0;
return (strtotime($date) - time()) / (60 * 60 * 24); // Days from now
}
private function parsePriorityPredictions($response) {
return array_map(function($prediction) {
return $prediction[0]; // Assuming single output
}, $response['predictions']);
}
}
1.2 AI-Powered Chatbot & Virtual Assistant
<?php
// ai/ChatbotService.php
class ChatbotService {
private $aiService;
private $contextManager;
private $actionExecutor;
public function __construct() {
$this->aiService = new AIService();
$this->contextManager = new ConversationContextManager();
$this->actionExecutor = new ActionExecutor();
}
public function processMessage($userId, $message, $conversationContext = []) {
// Update conversation context
$context = $this->contextManager->updateContext($userId, $message, $conversationContext);
// Determine intent
$intent = $this->detectIntent($message, $context);
// Execute appropriate action
$response = $this->executeAction($intent, $message, $context);
// Update context with response
$this->contextManager->saveContext($userId, $message, $response, $intent);
return [
'response' => $response,
'intent' => $intent,
'suggested_actions' => $this->getSuggestedActions($intent, $context)
];
}
private function detectIntent($message, $context) {
$response = $this->aiService->openAIClient->chat()->create([
'model' => 'gpt-4',
'messages' => [
[
'role' => 'system',
'content' => "You are a project management assistant. Classify the user's intent into one of these categories:
- task_create: User wants to create a task
- task_update: User wants to update a task
- task_query: User wants information about tasks
- project_info: User wants project information
- report_request: User wants a report
- help: User needs help
- small_talk: Casual conversation
Respond with only the intent category."
],
[
'role' => 'user',
'content' => $message
]
],
'temperature' => 0.1,
'max_tokens' => 10
]);
return trim($response->choices[0]->message->content);
}
private function executeAction($intent, $message, $context) {
switch ($intent) {
case 'task_create':
return $this->actionExecutor->createTaskFromMessage($message, $context);
case 'task_query':
return $this->actionExecutor->queryTasks($message, $context);
case 'project_info':
return $this->actionExecutor->getProjectInfo($message, $context);
case 'report_request':
return $this->actionExecutor->generateReport($message, $context);
case 'help':
return $this->getHelpResponse();
case 'small_talk':
return $this->generateSmallTalkResponse($message);
default:
return "I'm not sure how to help with that. Could you rephrase?";
}
}
private function getSuggestedActions($intent, $context) {
$suggestions = [
'task_create' => ['Create another task', 'View my tasks'],
'task_query' => ['Show overdue tasks', 'Show tasks due today'],
'project_info' => ['Project progress', 'Team workload'],
'report_request' => ['Weekly report', 'Project status report']
];
return $suggestions[$intent] ?? ['Get help', 'View projects'];
}
}
// ai/ActionExecutor.php
class ActionExecutor {
private $taskRepository;
private $projectRepository;
public function __construct() {
$this->taskRepository = new TaskRepository();
$this->projectRepository = new ProjectRepository();
}
public function createTaskFromMessage($message, $context) {
// Extract task details using AI
$extractedData = $this->extractTaskData($message);
if (empty($extractedData['title'])) {
return "I need more information to create a task. What should the task be about?";
}
// Create task
$task = $this->taskRepository->create([
'title' => $extractedData['title'],
'description' => $extractedData['description'] ?? '',
'due_date' => $extractedData['due_date'] ?? null,
'project_id' => $extractedData['project_id'] ?? $context['current_project_id'],
'assigned_to' => $extractedData['assigned_to'] ?? $context['user_id']
]);
return "I've created the task '{$task->title}'" .
($task->due_date ? " due on {$task->due_date}" : "") .
". Would you like to add more details?";
}
public function queryTasks($message, $context) {
$filters = $this->extractTaskFilters($message);
$tasks = $this->taskRepository->getWithFilters($filters);
if (empty($tasks)) {
return "I couldn't find any tasks matching your criteria.";
}
$response = "I found " . count($tasks) . " tasks:\n\n";
foreach (array_slice($tasks, 0, 5) as $task) {
$response .= "• {$task->title}";
if ($task->due_date) {
$response .= " (Due: {$task->due_date})";
}
$response .= "\n";
}
if (count($tasks) > 5) {
$response .= "\nAnd " . (count($tasks) - 5) . " more tasks...";
}
return $response;
}
private function extractTaskData($message) {
// Use AI to extract structured data from natural language
$response = $this->aiService->openAIClient->chat()->create([
'model' => 'gpt-4',
'messages' => [
[
'role' => 'system',
'content' => 'Extract task information from the message. Respond with JSON: {"title": "", "description": "", "due_date": "", "priority": ""}'
],
[
'role' => 'user',
'content' => $message
]
],
'response_format' => ['type' => 'json_object']
]);
return json_decode($response->choices[0]->message->content, true);
}
}
Part 2: Real-time Systems with WebSockets
2.1 Advanced WebSocket Server
<?php
// realtime/WebSocketServer.php
class WebSocketServer {
private $server;
private $clients;
private $rooms;
private $subscriptions;
public function __construct($host = '0.0.0.0', $port = 8080) {
$this->server = new Swoole\WebSocket\Server($host, $port);
$this->clients = new SplObjectStorage();
$this->rooms = [];
$this->subscriptions = [];
$this->setupEventHandlers();
}
public function start() {
$this->server->start();
}
private function setupEventHandlers() {
$this->server->on('start', function ($server) {
echo "WebSocket server started at ws://{$server->host}:{$server->port}\n";
});
$this->server->on('open', function ($server, $request) {
$this->handleConnection($request);
});
$this->server->on('message', function ($server, $frame) {
$this->handleMessage($frame);
});
$this->server->on('close', function ($server, $fd) {
$this->handleDisconnection($fd);
});
}
private function handleConnection($request) {
$clientId = $request->fd;
$user = $this->authenticateConnection($request);
if (!$user) {
$this->server->push($clientId, json_encode([
'type' => 'error',
'message' => 'Authentication failed'
]));
$this->server->close($clientId);
return;
}
$client = [
'id' => $clientId,
'user' => $user,
'connected_at' => time(),
'last_activity' => time()
];
$this->clients->attach((object)$client);
// Join user to their personal room
$this->joinRoom($clientId, "user_{$user['id']}");
// Join user to project rooms they have access to
$this->joinUserProjectRooms($clientId, $user['id']);
$this->broadcastToRoom("user_{$user['id']}", [
'type' => 'connection_established',
'client_id' => $clientId,
'user' => $user
]);
echo "Client {$clientId} connected (User: {$user['email']})\n";
}
private function handleMessage($frame) {
$client = $this->getClient($frame->fd);
if (!$client) {
return;
}
// Update last activity
$client->last_activity = time();
try {
$message = json_decode($frame->data, true);
if (!isset($message['type'])) {
throw new InvalidArgumentException('Message type is required');
}
switch ($message['type']) {
case 'subscribe':
$this->handleSubscribe($client, $message);
break;
case 'unsubscribe':
$this->handleUnsubscribe($client, $message);
break;
case 'chat_message':
$this->handleChatMessage($client, $message);
break;
case 'typing_start':
case 'typing_stop':
$this->handleTypingIndicator($client, $message);
break;
case 'ping':
$this->sendToClient($client->id, ['type' => 'pong']);
break;
default:
$this->sendToClient($client->id, [
'type' => 'error',
'message' => 'Unknown message type'
]);
}
} catch (Exception $e) {
$this->sendToClient($client->id, [
'type' => 'error',
'message' => $e->getMessage()
]);
}
}
private function handleSubscribe($client, $message) {
if (!isset($message['channel'])) {
throw new InvalidArgumentException('Channel is required for subscription');
}
$channel = $message['channel'];
$this->subscribeToChannel($client->id, $channel);
$this->sendToClient($client->id, [
'type' => 'subscribed',
'channel' => $channel
]);
}
private function handleChatMessage($client, $message) {
if (!isset($message['room']) || !isset($message['content'])) {
throw new InvalidArgumentException('Room and content are required for chat messages');
}
// Validate user has access to room
if (!$this->canAccessRoom($client->user['id'], $message['room'])) {
throw new RuntimeException('Access denied to room');
}
// Store message in database
$chatMessage = $this->storeChatMessage(
$client->user['id'],
$message['room'],
$message['content']
);
// Broadcast to room
$this->broadcastToRoom($message['room'], [
'type' => 'chat_message',
'message' => $chatMessage,
'user' => $client->user
]);
// Notify AI service for analysis (if enabled)
if (env('AI_CHAT_ANALYSIS_ENABLED')) {
$this->analyzeChatMessage($chatMessage);
}
}
private function handleTypingIndicator($client, $message) {
if (!isset($message['room'])) {
return;
}
$this->broadcastToRoom($message['room'], [
'type' => $message['type'],
'user' => [
'id' => $client->user['id'],
'name' => $client->user['name']
],
'room' => $message['room']
], $client->id); // Don't send to the user who is typing
}
public function broadcastToRoom($room, $data, $excludeClientId = null) {
if (!isset($this->rooms[$room])) {
return;
}
$message = json_encode($data);
foreach ($this->rooms[$room] as $clientId) {
if ($clientId !== $excludeClientId && $this->server->exist($clientId)) {
$this->server->push($clientId, $message);
}
}
}
public function sendToUser($userId, $data) {
$this->broadcastToRoom("user_{$userId}", $data);
}
private function joinRoom($clientId, $room) {
if (!isset($this->rooms[$room])) {
$this->rooms[$room] = [];
}
$this->rooms[$room][] = $clientId;
$this->rooms[$room] = array_unique($this->rooms[$room]);
}
private function subscribeToChannel($clientId, $channel) {
if (!isset($this->subscriptions[$channel])) {
$this->subscriptions[$channel] = [];
}
$this->subscriptions[$channel][] = $clientId;
$this->subscriptions[$channel] = array_unique($this->subscriptions[$channel]);
}
}
2.2 Real-time Collaboration Features
<?php
// realtime/CollaborationService.php
class CollaborationService {
private $webSocketServer;
private $documentManager;
private $presenceTracker;
public function __construct(WebSocketServer $webSocketServer) {
$this->webSocketServer = $webSocketServer;
$this->documentManager = new DocumentManager();
$this->presenceTracker = new PresenceTracker();
}
// Real-time document editing
public function handleDocumentOperation($clientId, $operation) {
$document = $this->documentManager->getDocument($operation['document_id']);
if (!$this->canEditDocument($clientId, $document)) {
throw new RuntimeException('No permission to edit document');
}
// Apply operation to document
$updatedDocument = $this->documentManager->applyOperation(
$operation['document_id'],
$operation
);
// Broadcast to other collaborators
$this->broadcastToCollaborators($operation['document_id'], [
'type' => 'document_operation',
'operation' => $operation,
'document' => $updatedDocument,
'client_id' => $clientId
], $clientId);
return $updatedDocument;
}
// Real-time cursor positions
public function updateCursorPosition($clientId, $data) {
$this->presenceTracker->updateCursorPosition(
$clientId,
$data['document_id'],
$data['position']
);
$this->broadcastToCollaborators($data['document_id'], [
'type' => 'cursor_update',
'user_id' => $this->getClientUserId($clientId),
'position' => $data['position'],
'document_id' => $data['document_id']
], $clientId);
}
// Real-time selection updates
public function updateSelection($clientId, $data) {
$this->presenceTracker->updateSelection(
$clientId,
$data['document_id'],
$data['selection']
);
$this->broadcastToCollaborators($data['document_id'], [
'type' => 'selection_update',
'user_id' => $this->getClientUserId($clientId),
'selection' => $data['selection'],
'document_id' => $data['document_id']
], $clientId);
}
// Get active collaborators
public function getActiveCollaborators($documentId) {
return $this->presenceTracker->getActiveUsers($documentId);
}
// Handle user joining document
public function userJoinedDocument($clientId, $documentId) {
$user = $this->getClientUser($clientId);
$this->presenceTracker->userJoined($clientId, $documentId, $user);
// Notify other users
$this->broadcastToCollaborators($documentId, [
'type' => 'user_joined',
'user' => $user,
'document_id' => $documentId
], $clientId);
// Send current document state to joining user
$document = $this->documentManager->getDocument($documentId);
$collaborators = $this->getActiveCollaborators($documentId);
$this->webSocketServer->sendToClient($clientId, [
'type' => 'document_state',
'document' => $document,
'collaborators' => $collaborators
]);
}
// Handle user leaving document
public function userLeftDocument($clientId, $documentId) {
$user = $this->getClientUser($clientId);
$this->presenceTracker->userLeft($clientId, $documentId);
$this->broadcastToCollaborators($documentId, [
'type' => 'user_left',
'user' => $user,
'document_id' => $documentId
]);
}
private function broadcastToCollaborators($documentId, $data, $excludeClientId = null) {
$room = "document_{$documentId}";
$this->webSocketServer->broadcastToRoom($room, $data, $excludeClientId);
}
private function canEditDocument($clientId, $document) {
$user = $this->getClientUser($clientId);
return in_array($user['id'], $document['collaborators']);
}
}
// realtime/PresenceTracker.php
class PresenceTracker {
private $redis;
public function __construct() {
$this->redis = new Redis();
}
public function userJoined($clientId, $documentId, $user) {
$key = "presence:document:{$documentId}";
$this->redis->hset($key, $clientId, json_encode([
'user_id' => $user['id'],
'user_name' => $user['name'],
'joined_at' => time(),
'last_seen' => time()
]));
$this->redis->expire($key, 3600); // Expire after 1 hour of inactivity
}
public function userLeft($clientId, $documentId) {
$key = "presence:document:{$documentId}";
$this->redis->hdel($key, $clientId);
}
public function updateCursorPosition($clientId, $documentId, $position) {
$key = "presence:document:{$documentId}";
if ($this->redis->hexists($key, $clientId)) {
$data = json_decode($this->redis->hget($key, $clientId), true);
$data['cursor_position'] = $position;
$data['last_seen'] = time();
$this->redis->hset($key, $clientId, json_encode($data));
}
}
public function getActiveUsers($documentId) {
$key = "presence:document:{$documentId}";
$users = $this->redis->hgetall($key);
$activeUsers = [];
$now = time();
foreach ($users as $clientId => $userData) {
$data = json_decode($userData, true);
// Remove inactive users (more than 30 seconds)
if ($now - $data['last_seen'] > 30) {
$this->redis->hdel($key, $clientId);
continue;
}
$activeUsers[] = $data;
}
return $activeUsers;
}
}
Part 3: Blockchain & Web3 Integration
3.1 Smart Contract Integration & NFT Features
<?php
// blockchain/Web3Service.php
class Web3Service {
private $web3;
private $contracts;
private $walletManager;
public function __construct() {
$this->web3 = new Web3(env('WEB3_PROVIDER_URL'));
$this->walletManager = new WalletManager();
$this->loadContracts();
}
public function createProjectNFT($projectId, $metadata) {
$project = Project::find($projectId);
if (!$project) {
throw new Exception('Project not found');
}
// Prepare NFT metadata
$nftMetadata = [
'name' => $project->name,
'description' => $project->description,
'image' => $this->generateProjectImage($project),
'attributes' => [
[
'trait_type' => 'Project ID',
'value' => $project->id
],
[
'trait_type' => 'Status',
'value' => $project->status
],
[
'trait_type' => 'Created Date',
'value' => $project->created_at->toISOString()
]
]
];
// Upload metadata to IPFS
$metadataUri = $this->uploadToIPFS($nftMetadata);
// Mint NFT
$transaction = $this->mintNFT(
$project->owner->wallet_address,
$metadataUri
);
// Store NFT details
$nft = NFT::create([
'project_id' => $project->id,
'token_id' => $transaction->tokenId,
'contract_address' => env('NFT_CONTRACT_ADDRESS'),
'metadata_uri' => $metadataUri,
'transaction_hash' => $transaction->hash,
'owner_address' => $project->owner->wallet_address
]);
return $nft;
}
public function createAchievementToken($userId, $achievementType) {
$user = User::find($userId);
$achievement = $this->getAchievementConfig($achievementType);
$metadata = [
'name' => $achievement['name'],
'description' => $achievement['description'],
'image' => $achievement['image'],
'attributes' => [
[
'trait_type' => 'Type',
'value' => $achievementType
],
[
'trait_type' => 'Rarity',
'value' => $achievement['rarity']
]
]
];
$metadataUri = $this->uploadToIPFS($metadata);
$transaction = $this->mintAchievementToken(
$user->wallet_address,
$metadataUri
);
return [
'token_id' => $transaction->tokenId,
'transaction_hash' => $transaction->hash,
'metadata_uri' => $metadataUri
];
}
public function verifyOwnership($walletAddress, $tokenId) {
$contract = $this->contracts['nft'];
try {
$owner = $contract->methods->ownerOf($tokenId)->call();
return strtolower($owner) === strtolower($walletAddress);
} catch (Exception $e) {
return false;
}
}
public function getWalletNFTs($walletAddress) {
$contract = $this->contracts['nft'];
// Get balance
$balance = $contract->methods->balanceOf($walletAddress)->call();
$nfts = [];
for ($i = 0; $i < $balance; $i++) {
$tokenId = $contract->methods->tokenOfOwnerByIndex($walletAddress, $i)->call();
$tokenUri = $contract->methods->tokenURI($tokenId)->call();
$nfts[] = [
'token_id' => $tokenId,
'token_uri' => $tokenUri,
'metadata' => $this->fetchMetadata($tokenUri)
];
}
return $nfts;
}
private function mintNFT($toAddress, $metadataUri) {
$contract = $this->contracts['nft'];
$privateKey = env('NFT_MINTER_PRIVATE_KEY');
$nonce = $this->web3->eth->getTransactionCount(
env('NFT_MINTER_ADDRESS'),
'pending'
);
$transaction = $contract->methods->mint($toAddress, $metadataUri);
$data = $transaction->encodeABI();
$signedTransaction = $this->signTransaction([
'nonce' => $nonce,
'from' => env('NFT_MINTER_ADDRESS'),
'to' => env('NFT_CONTRACT_ADDRESS'),
'value' => '0x0',
'gas' => '0x' . dechex(200000),
'gasPrice' => $this->web3->eth->gasPrice(),
'data' => $data
], $privateKey);
$transactionHash = $this->web3->eth->sendRawTransaction($signedTransaction);
// Wait for transaction receipt
return $this->waitForTransaction($transactionHash);
}
private function uploadToIPFS($data) {
$client = new Client();
$response = $client->post('https://api.pinata.cloud/pinning/pinJSONToIPFS', [
'headers' => [
'pinata_api_key' => env('PINATA_API_KEY'),
'pinata_secret_api_key' => env('PINATA_SECRET_API_KEY'),
],
'json' => [
'pinataContent' => $data,
'pinataMetadata' => [
'name' => 'project-nft-metadata.json'
]
]
]);
$result = json_decode($response->getBody(), true);
return "ipfs://" . $result['IpfsHash'];
}
private function loadContracts() {
$this->contracts['nft'] = new Contract($this->web3->provider, $this->getNFTABI());
$this->contracts['nft']->at(env('NFT_CONTRACT_ADDRESS'));
}
private function getNFTABI() {
return json_decode(file_get_contents(storage_path('abis/NFTContract.json')), true);
}
}
Part 4: Advanced Search with Elasticsearch
4.1 Advanced Search Service
<?php
// search/AdvancedSearchService.php
class AdvancedSearchService {
private $elasticsearch;
private $indexManager;
public function __construct() {
$this->elasticsearch = Elasticsearch\ClientBuilder::create()
->setHosts([env('ELASTICSEARCH_HOST')])
->build();
$this->indexManager = new IndexManager($this->elasticsearch);
}
public function searchProjects($query, $filters = [], $page = 1, $perPage = 20) {
$searchParams = [
'index' => 'projects',
'body' => [
'from' => ($page - 1) * $perPage,
'size' => $perPage,
'query' => $this->buildProjectQuery($query, $filters),
'sort' => $this->buildSort($filters),
'aggs' => $this->buildAggregations()
]
];
$response = $this->elasticsearch->search($searchParams);
return [
'results' => $this->formatProjectResults($response),
'total' => $response['hits']['total']['value'],
'aggregations' => $response['aggregations'] ?? [],
'page' => $page,
'per_page' => $perPage
];
}
public function semanticSearch($query, $context = []) {
// Use vector search for semantic similarity
$vector = $this->generateQueryVector($query);
$searchParams = [
'index' => 'projects',
'body' => [
'query' => [
'script_score' => [
'query' => ['match_all' => {}],
'script' => [
'source' => "cosineSimilarity(params.query_vector, 'embedding') + 1.0",
'params' => ['query_vector' => $vector]
]
]
],
'size' => 10
]
];
$response = $this->elasticsearch->search($searchParams);
return $this->formatProjectResults($response);
}
public function advancedFacetedSearch($searchRequest) {
$boolQuery = ['bool' => ['must' => []]];
// Text search across multiple fields
if (!empty($searchRequest['q'])) {
$boolQuery['bool']['must'][] = [
'multi_match' => [
'query' => $searchRequest['q'],
'fields' => [
'title^3',
'description^2',
'tags^2',
'content'
],
'fuzziness' => 'AUTO'
]
];
}
// Date range filters
if (!empty($searchRequest['date_range'])) {
$boolQuery['bool']['filter'][] = [
'range' => [
'created_at' => [
'gte' => $searchRequest['date_range']['start'],
'lte' => $searchRequest['date_range']['end']
]
]
];
}
// Geo search (if location data available)
if (!empty($searchRequest['location'])) {
$boolQuery['bool']['filter'][] = [
'geo_distance' => [
'distance' => $searchRequest['location']['radius'] . 'km',
'location' => [
'lat' => $searchRequest['location']['lat'],
'lon' => $searchRequest['location']['lon']
]
]
];
}
// Custom scoring based on business rules
$functionScore = [
'query' => $boolQuery,
'functions' => [
[
'filter' => ['term' => ['status' => 'active']],
'weight' => 2
],
[
'filter' => ['range' => ['completion_rate' => ['gte' => 0.8]]],
'weight' => 1.5
],
[
'field_value_factor' => [
'field' => 'priority',
'factor' => 1.2,
'modifier' => 'sqrt'
]
]
],
'score_mode' => 'multiply'
];
$searchParams = [
'index' => 'projects',
'body' => [
'query' => ['function_score' => $functionScore],
'aggs' => $this->buildAdvancedAggregations(),
'highlight' => [
'fields' => [
'title' => new \stdClass(),
'description' => new \stdClass(),
'content' => new \stdClass()
]
]
]
];
$response = $this->elasticsearch->search($searchParams);
return $this->formatAdvancedResults($response);
}
private function buildProjectQuery($query, $filters) {
$boolQuery = ['bool' => []];
if (!empty($query)) {
$boolQuery['bool']['must'] = [
'multi_match' => [
'query' => $query,
'fields' => ['title^3', 'description^2', 'tags'],
'type' => 'best_fields',
'fuzziness' => 'AUTO'
]
];
}
// Add filters
if (!empty($filters['status'])) {
$boolQuery['bool']['filter'][] = ['term' => ['status' => $filters['status']]];
}
if (!empty($filters['tags'])) {
$boolQuery['bool']['filter'][] = ['terms' => ['tags' => $filters['tags']]];
}
if (!empty($filters['date_range'])) {
$boolQuery['bool']['filter'][] = [
'range' => [
'created_at' => [
'gte' => $filters['date_range']['start'],
'lte' => $filters['date_range']['end']
]
]
];
}
return $boolQuery;
}
private function generateQueryVector($query) {
// Use OpenAI embeddings to generate query vector
$response = (new AIService())->openAIClient->embeddings()->create([
'model' => 'text-embedding-ada-002',
'input' => $query
]);
return $response->data[0]->embedding;
}
public function reindexAllProjects() {
$this->indexManager->recreateIndex('projects');
$projects = Project::with(['tasks', 'users', 'tags'])->chunk(100, function($projects) {
$bulkData = [];
foreach ($projects as $project) {
$bulkData[] = ['index' => ['_index' => 'projects', '_id' => $project->id]];
$bulkData[] = $this->formatProjectForIndex($project);
}
$this->elasticsearch->bulk(['body' => $bulkData]);
});
}
private function formatProjectForIndex($project) {
return [
'title' => $project->title,
'description' => $project->description,
'status' => $project->status,
'tags' => $project->tags->pluck('name')->toArray(),
'created_at' => $project->created_at->toISOString(),
'updated_at' => $project->updated_at->toISOString(),
'completion_rate' => $project->completion_rate,
'priority' => $project->priority_level,
'embedding' => $project->embedding, // Pre-computed vector
'suggest' => [
'input' => array_merge(
[$project->title],
$project->tags->pluck('name')->toArray(),
explode(' ', $project->description)
)
]
];
}
}
Part 5: Advanced DevOps & SRE Practices
5.1 Kubernetes Deployment & Service Mesh
# kubernetes/deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: saas-app namespace: production spec: replicas: 3 selector: matchLabels: app: saas-app template: metadata: labels: app: saas-app version: v1.2.0 spec: containers: - name: app image: ghcr.io/your-org/saas-app:latest ports: - containerPort: 80 env: - name: APP_ENV value: production - name: APP_DEBUG value: "false" resources: requests: memory: "256Mi" cpu: "250m" limits: memory: "512Mi" cpu: "500m" livenessProbe: httpGet: path: /health port: 80 initialDelaySeconds: 30 periodSeconds: 10 readinessProbe: httpGet: path: /health/ready port: 80 initialDelaySeconds: 5 periodSeconds: 5 volumeMounts: - name: storage mountPath: /var/www/storage - name: queue-worker image: ghcr.io/your-org/saas-app:latest command: ["php", "artisan", "queue:work", "--sleep=3", "--tries=3"] resources: requests: memory: "128Mi" cpu: "100m" limits: memory: "256Mi" cpu: "200m" volumeMounts: - name: storage mountPath: /var/www/storage volumes: - name: storage persistentVolumeClaim: claimName: app-storage --- apiVersion: v1 kind: Service metadata: name: saas-app-service namespace: production spec: selector: app: saas-app ports: - port: 80 targetPort: 80 type: ClusterIP --- apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: saas-app-vs namespace: production spec: hosts: - saas-app-service.production.svc.cluster.local http: - route: - destination: host: saas-app-service.production.svc.cluster.local subset: v1 retries: attempts: 3 perTryTimeout: 2s timeout: 10s fault: abort: percentage: value: 0.1 httpStatus: 500
5.2 Advanced Monitoring & SRE Dashboard
<?php
// monitoring/SREDashboard.php
class SREDashboard {
private $prometheus;
private $alertManager;
private $sloCalculator;
public function __construct() {
$this->prometheus = new Prometheus();
$this->alertManager = new AlertManager();
$this->sloCalculator = new SLOCalculator();
}
public function getServiceLevelIndicators() {
return [
'availability' => $this->calculateAvailability(),
'latency' => $this->calculateLatencySLO(),
'error_rate' => $this->calculateErrorRate(),
'throughput' => $this->calculateThroughput()
];
}
public function getErrorBudget($sloTarget = 0.999) {
$currentSLO = $this->calculateAvailability();
$errorBudget = 1 - $sloTarget;
$remainingBudget = $currentSLO - $sloTarget;
return [
'slo_target' => $sloTarget,
'current_slo' => $currentSLO,
'error_budget_remaining' => max(0, $remainingBudget / $errorBudget),
'burn_rate' => $this->calculateBurnRate()
];
}
public function getPerformanceMetrics() {
return [
'p50_latency' => $this->getQuantileLatency(0.5),
'p95_latency' => $this->getQuantileLatency(0.95),
'p99_latency' => $this->getQuantileLatency(0.99),
'requests_per_second' => $this->getRequestsPerSecond(),
'concurrent_connections' => $this->getConcurrentConnections(),
'memory_usage' => $this->getMemoryUsage(),
'cpu_usage' => $this->getCPUUsage()
];
}
public function getBusinessMetrics() {
return [
'active_users' => $this->getActiveUsers(),
'new_signups' => $this->getNewSignups(),
'projects_created' => $this->getProjectsCreated(),
'tasks_completed' => $this->getTasksCompleted(),
'api_usage' => $this->getAPIUsage()
];
}
public function generateSREReport($timeRange = '7d') {
return [
'time_range' => $timeRange,
'service_levels' => $this->getServiceLevelIndicators(),
'performance' => $this->getPerformanceMetrics(),
'business_metrics' => $this->getBusinessMetrics(),
'incidents' => $this->getIncidents($timeRange),
'recommendations' => $this->generateRecommendations()
];
}
private function calculateAvailability() {
$totalRequests = $this->prometheus->query('http_requests_total');
$successfulRequests = $this->prometheus->query('http_requests_total{status=~"2..|3.."}');
if ($totalRequests > 0) {
return $successfulRequests / $totalRequests;
}
return 1.0;
}
private function calculateBurnRate() {
// Calculate how quickly error budget is being consumed
$errorRate = 1 - $this->calculateAvailability();
$timeWindow = 3600; // 1 hour
return $errorRate * $timeWindow / 3600;
}
private function generateRecommendations() {
$recommendations = [];
$availability = $this->calculateAvailability();
if ($availability < 0.999) {
$recommendations[] = [
'type' => 'critical',
'message' => 'Availability below SLO target. Consider scaling or optimizing critical endpoints.',
'action' => 'Review error rates and latency for high-traffic endpoints'
];
}
$p95Latency = $this->getQuantileLatency(0.95);
if ($p95Latency > 2.0) {
$recommendations[] = [
'type' => 'warning',
'message' => 'P95 latency above 2 seconds. Users may experience slow performance.',
'action' => 'Optimize database queries and consider caching strategies'
];
}
$memoryUsage = $this->getMemoryUsage();
if ($memoryUsage > 0.8) {
$recommendations[] = [
'type' => 'warning',
'message' => 'High memory usage detected. Risk of out-of-memory errors.',
'action' => 'Increase memory limits or optimize memory usage'
];
}
return $recommendations;
}
}
Key Cutting-Edge Features Covered:
-
AI Integration: GPT-4, embeddings, ML-powered features
-
Real-time Systems: WebSockets, collaboration, live updates
-
Blockchain & Web3: NFT integration, smart contracts
-
Advanced Search: Elasticsearch, semantic search, vector databases
-
SRE Practices: SLO monitoring, error budgets, reliability engineering
-
Cloud Native: Kubernetes, service mesh, cloud deployment
Enterprise-Grade Innovation:
-
AI-Powered UX: Smart assistants, automated content generation
-
Real-time Collaboration: Live editing, presence indicators
-
Web3 Features: Digital ownership, achievement tokens
-
Advanced Search: Semantic understanding, faceted navigation
-
Production Excellence: SRE practices, advanced monitoring
-
Scalability: Microservices, cloud-native architecture
This lesson represents the absolute frontier of PHP development, integrating cutting-edge technologies and practices that power modern, innovative applications at scale!
What's Your Reaction?