diff --git a/packages/docs/site/docs/developers/05-local-development/03-php-wasm-node.md b/packages/docs/site/docs/developers/05-local-development/03-php-wasm-node.md index cc75499dc2..fde2dca660 100644 --- a/packages/docs/site/docs/developers/05-local-development/03-php-wasm-node.md +++ b/packages/docs/site/docs/developers/05-local-development/03-php-wasm-node.md @@ -1,20 +1,642 @@ --- title: php-wasm/node slug: /developers/local-development/php-wasm-node +description: WordPress Playground brings WebAssembly-powered PHP to Node.js for server-side execution, data processing, and testing without a native install. --- # Using WordPress Playground in Node.js As a WebAssembly project, you can also use WordPress Playground in Node.js. -If you need low-level control over the underlying WebAssembly PHP build, take a look at the [`@php-wasm/node` package](https://npmjs.org/@php-wasm/node) which ships the PHP WebAssembly runtime. This package is at the core of all WordPress Playground tools for Node.js. - -:::info **API reference** +If you need low-level control over the underlying WebAssembly PHP build, take a look at the [@php-wasm/node package](https://npmjs.org/@php-wasm/node) which ships the PHP WebAssembly runtime. This package is at the core of all WordPress Playground tools for Node.js. Consult the [complete list](/api/node) of Classes, Functions, Interfaces, and Type Aliases. -::: +## WebAssembly PHP for Node.js + +This package ships WebAssembly PHP binaries and the JavaScript API optimized for Node.js. It uses the host file system directly and can access the network if you plug in a custom WS proxy. + +### Basic usage + +```javascript +import { PHP } from '@php-wasm/universal'; +import { loadNodeRuntime } from '@php-wasm/node'; + +const php = new PHP(await loadNodeRuntime('8.3')); +const output = await php.runStream({ + code: '', +}); +console.log(await output.stdoutText); +``` + +## Use cases + +### Server-side PHP execution + +You can run PHP scripts in Node.js environments without installing PHP natively. Perfect for: + +- CI/CD pipelines that need PHP execution +- Microservices that occasionally need PHP functionality +- Development tools and build scripts + +### Data processing and transformation + +You can process and manipulate data using PHP's rich ecosystem: + +- CSV, JSON, and XML data transformation +- SQLite database operations without external dependencies +- Archive creation and extraction (ZIP, TAR) +- Image processing and manipulation + +### Template rendering and content generation + +You can generate dynamic content using PHP templates: + +- Email template rendering +- HTML report generation +- Documentation generation +- Dynamic configuration file creation + +### API development and testing + +You can build and test API endpoints: + +- Mock API servers for testing +- Request/response simulation +- API endpoint prototyping +- Integration testing for PHP APIs + +### PHP code analysis and testing + +You can build tools that analyze, lint, or test PHP code: + +- Static analysis tools +- Code formatters and validators +- Unit test runners +- Documentation generators + +### Legacy code integration + +You can bridge PHP and JavaScript ecosystems: + +- Migrate PHP applications incrementally +- Use PHP libraries in JavaScript projects +- Run PHP alongside modern JavaScript frameworks +- Provide backward compatibility + +### Educational platforms + +You can create interactive PHP learning environments: + +- Online coding tutorials +- Interactive documentation +- Code playgrounds and sandboxes +- Programming challenges + +### WordPress development tools + +You can build WordPress development utilities: + +- Plugin/theme validators +- WordPress CLI alternatives +- Development environment bootstrapping +- Automated testing tools + +## Practical demos + +### Demo 1: File system operations + +Execute PHP scripts that interact with the file system: + +```javascript +import { PHP } from '@php-wasm/universal'; +import { loadNodeRuntime } from '@php-wasm/node'; + +const php = new PHP(await loadNodeRuntime('8.3')); + +// Create directory structure +php.mkdir('/app/data'); + +// Write configuration file +await php.writeFile( + '/app/config.json', + JSON.stringify({ + app: 'MyApp', + version: '1.0.0', + debug: true, + }) +); + +// Create and run PHP script that reads the config +await php.writeFile( + '/app/index.php', + `` +); + +const result = await php.runStream({ scriptPath: '/app/index.php' }); +console.log(await result.stdoutText); +``` + +### Demo 2: SQLite database operations + +Use PHP's SQLite extension for data storage: + +```javascript +import { PHP } from '@php-wasm/universal'; +import { loadNodeRuntime } from '@php-wasm/node'; + +const php = new PHP(await loadNodeRuntime('8.3')); + +// Create directory for database +php.mkdir('/data'); + +// Create database, insert data, and query +const result = await php.runStream({ + code: `exec('CREATE TABLE IF NOT EXISTS users ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + name TEXT NOT NULL, + email TEXT UNIQUE NOT NULL, + created_at DATETIME DEFAULT CURRENT_TIMESTAMP +)'); + +// Insert sample data +$stmt = $db->prepare('INSERT INTO users (name, email) VALUES (?, ?)'); +$users = [ + ['Alice Johnson', 'alice@example.com'], + ['Bob Smith', 'bob@example.com'], + ['Charlie Davis', 'charlie@example.com'] +]; + +foreach ($users as $user) { + $stmt->bindValue(1, $user[0]); + $stmt->bindValue(2, $user[1]); + $stmt->execute(); +} + +// Query data +echo "All Users:\\n"; +echo str_repeat('-', 50) . "\\n"; +$results = $db->query('SELECT * FROM users ORDER BY name'); +while ($row = $results->fetchArray(SQLITE3_ASSOC)) { + echo "ID: {$row['id']} | {$row['name']} ({$row['email']})\\n"; +} + +$db->close(); +?>`, +}); + +console.log(await result.stdoutText); + +// Database file persists in the virtual file system +const dbExists = await php.fileExists('/data/app.db'); +console.log('\nDatabase persisted:', dbExists); +``` + +### Demo 3: Processing uploaded files (ZIP archives) + +Process ZIP files using PHP's Libzip extension: + +```javascript +import { PHP } from '@php-wasm/universal'; +import { loadNodeRuntime } from '@php-wasm/node'; + +const php = new PHP(await loadNodeRuntime('8.3')); + +// Create sample files +php.mkdir('/uploads'); +await php.writeFile('/uploads/readme.txt', 'This is a sample text file'); +await php.writeFile('/uploads/data.json', JSON.stringify({ name: 'Test', version: '1.0' })); + +// Create, process, and extract ZIP archive +const result = await php.runStream({ + code: `open('/uploads/archive.zip', ZipArchive::CREATE); +$zip->addFromString('readme.txt', file_get_contents('/uploads/readme.txt')); +$zip->addFromString('data.json', file_get_contents('/uploads/data.json')); +$zip->addFromString('info.txt', 'Created with PHP WASM'); +$zip->close(); + +echo "ZIP archive created successfully\\n\\n"; + +// Read and display archive contents +$zip->open('/uploads/archive.zip'); +echo "Archive Contents:\\n"; +echo str_repeat('=', 50) . "\\n"; + +for ($i = 0; $i < $zip->numFiles; $i++) { + $stat = $zip->statIndex($i); + $size = round($stat['size'] / 1024, 2); + echo sprintf("%-40s %10s KB\\n", $stat['name'], $size); +} + +// Extract files +$zip->extractTo('/uploads/extracted/'); +$zip->close(); + +echo "\\nExtracted successfully to /uploads/extracted/\\n"; + +// List extracted files +echo "\\nExtracted Files:\\n"; +$files = new RecursiveIteratorIterator( + new RecursiveDirectoryIterator('/uploads/extracted/') +); +foreach ($files as $file) { + if ($file->isFile()) { + echo " " . $file->getPathname() . "\\n"; + } +} +?>`, +}); + +console.log(await result.stdoutText); +``` + +### Demo 4: HTTP request/response pattern + +Simulate web server behavior with request handlers: + +```javascript +import { PHP } from '@php-wasm/universal'; +import { loadNodeRuntime } from '@php-wasm/node'; + +const php = new PHP(await loadNodeRuntime('8.3')); + +// Set up a simple API endpoint +await php.mkdir('/www/api'); +await php.writeFile( + '/www/api/users.php', + ` [ + ['id' => 1, 'name' => 'John Doe'], + ['id' => 2, 'name' => 'Jane Smith'] + ] + ]); + break; + + case 'POST': + $name = $input['name'] ?? 'Unknown'; + echo json_encode([ + 'success' => true, + 'user' => [ + 'id' => 3, + 'name' => $name + ], + 'message' => "User $name created" + ]); + break; + + default: + http_response_code(405); + echo json_encode(['error' => 'Method not allowed']); +} +?>` +); + +// Make GET request +const getResponse = await php.runStream({ + scriptPath: '/www/api/users.php', + env: { + REQUEST_METHOD: 'GET', + SERVER_NAME: 'localhost', + SERVER_PORT: '80', + }, +}); +console.log('GET Response:', await getResponse.stdoutText); + +// Make POST request +const postResponse = await php.runStream({ + scriptPath: '/www/api/users.php', + env: { + REQUEST_METHOD: 'POST', + SERVER_NAME: 'localhost', + SERVER_PORT: '80', + }, + body: JSON.stringify({ name: 'Alice Wonder' }), +}); +console.log('\\nPOST Response:', await postResponse.stdoutText); +``` + +### Demo 5: Template rendering engine + +Use PHP as a templating engine for dynamic content: + +```javascript +import { PHP } from '@php-wasm/universal'; +import { loadNodeRuntime } from '@php-wasm/node'; + +const php = new PHP(await loadNodeRuntime('8.3')); + +// Create templates directory +php.mkdir('/templates'); + +// Create template +await php.writeFile( + '/templates/email.php', + ` + + + + + +
+

Welcome, !

+
+
+

Thank you for registering with .

+

Your account details:

+ +

You now have access to the following features:

+ +
+ + +` +); + +// Render template with data +const templateData = { + name: 'Priya Sharma', + email: 'priya@example.com', + appName: 'MyAwesomeApp', + timestamp: Math.floor(Date.now() / 1000), + features: ['Dashboard Access', 'API Integration', 'Premium Support', 'Custom Branding'], +}; + +// Pass data to template via environment variables or files +await php.writeFile('/template-data.json', JSON.stringify(templateData)); + +const result = await php.runStream({ + code: ``, +}); + +console.log(await result.stdoutText); +// Now you have rendered HTML that can be sent via email or saved +``` + +### Demo 6: Real-time code execution and streaming + +Process PHP output as it's generated: + +```javascript +import { PHP } from '@php-wasm/universal'; +import { loadNodeRuntime } from '@php-wasm/node'; + +const php = new PHP(await loadNodeRuntime('8.3')); + +await php.writeFile( + '/stream-demo.php', + `` +); + +// Run PHP script +const streamedResponse = await php.runStream({ + scriptPath: '/stream-demo.php', +}); + +console.log('Processing PHP output:\n'); +console.log(await streamedResponse.stdoutText); +console.log(`\nExit code: ${streamedResponse.exitCode}`); +``` + +## Integration patterns + +### Pattern 1: Express.js middleware + +Integrate PHP processing into an Express.js application: + +```TypeScript +import express from 'express'; +import { PHP } from '@php-wasm/universal'; +import { loadNodeRuntime } from '@php-wasm/node'; + +const app = express(); +const php = new PHP(await loadNodeRuntime('8.3')); + +// PHP execution middleware +app.use('/php', async (req, res, next) => { + try { + const phpScript = req.query.script || 'index.php'; + const result = await php.runStream({ + scriptPath: `/www/${phpScript}`, + env: { + REQUEST_METHOD: req.method, + QUERY_STRING: new URLSearchParams( + req.query as Record + ).toString(), + REQUEST_URI: req.url, + }, + }); + + res.send(await result.stdoutText); + } catch (error) { + next(error); + } +}); + +app.listen(3000, () => { + console.log('Server with PHP support running on port 3000'); +}); +``` + +### Pattern 2: Automated testing + +Create automated tests for PHP code: + +```TypeScript +import { describe, it, expect, beforeAll } from '@jest/globals'; +import { PHP } from '@php-wasm/universal'; +import { loadNodeRuntime } from '@php-wasm/node'; + +describe('PHP Functions', () => { + let php: PHP; + + beforeAll(async () => { + php = new PHP(await loadNodeRuntime('8.3')); + }); + + it('should calculate sum correctly', async () => { + const result = await php.run({ + code: ``, + }); + + expect(result.text).toBe('8'); + }); + + it('should handle JSON operations', async () => { + const input = { name: 'Test', value: 42 }; + const result = await php.run({ + code: ` $input, + 'doubled' => $input['value'] * 2 + ]; + echo json_encode($output); + ?>`, + }); + + const output = JSON.parse(result.text); + expect(output.doubled).toBe(84); + }); +}); +``` + +### Pattern 3: Build tool integration + +Use in build scripts with other Node.js tools: + +```javascript +import { PHP } from '@php-wasm/universal'; +import { loadNodeRuntime } from '@php-wasm/node'; +import fs from 'fs/promises'; + +async function generateDocumentation() { + const php = new PHP(await loadNodeRuntime('8.3')); + + // Create output directory + php.mkdir('/output'); + + // Generate documentation + const result = await php.runStream({ + code: ``, + }); + + console.log(await result.stdoutText); + + // Extract generated docs back to Node.js file system + await fs.mkdir('./docs', { recursive: true }); + const summaryContent = await php.readFileAsText('/output/summary.md'); + await fs.writeFile('./docs/summary.md', summaryContent); + + console.log('Documentation saved to ./docs/summary.md'); +} + +generateDocumentation().catch(console.error); +``` + +## Advanced features + +### Working with environment variables + +```javascript +import { PHP } from '@php-wasm/universal'; +import { loadNodeRuntime } from '@php-wasm/node'; + +const php = new PHP(await loadNodeRuntime('8.3')); + +const result = await php.runStream({ + code: '', + env: { + CUSTOM_VAR: 'Hello from Node.js!', + }, +}); + +console.log(await result.stdoutText); +``` + +### Error handling + +```javascript +import { PHP } from '@php-wasm/universal'; +import { loadNodeRuntime } from '@php-wasm/node'; + +const php = new PHP(await loadNodeRuntime('8.3')); + +try { + const result = await php.runStream({ + code: '', + }); + + const stdout = await result.stdoutText; + const stderr = await result.stderrText; + + console.log('stdout:', stdout); + console.log('stderr:', stderr); + + if (stderr) { + console.error('PHP produced errors:', stderr); + } +} catch (error: any) { + console.error('JavaScript Error:', error.message); +} +``` -import PHPWASMNode from '@php-wasm/node/\README.md'; +## Performance considerations - +- **Reuse PHP instances**: Creating a new PHP instance is expensive. Reuse the same instance when possible. +- **Batch operations**: Group multiple file operations together rather than running separate scripts. +- **Memory management**: Large files may impact performance. Consider streaming for big datasets. +- **Caching**: Cache compiled PHP scripts and frequently accessed data. diff --git a/packages/docs/site/i18n/es/docusaurus-plugin-content-docs/current/developers/05-local-development/03-php-wasm-node.md b/packages/docs/site/i18n/es/docusaurus-plugin-content-docs/current/developers/05-local-development/03-php-wasm-node.md new file mode 100644 index 0000000000..724770e5fe --- /dev/null +++ b/packages/docs/site/i18n/es/docusaurus-plugin-content-docs/current/developers/05-local-development/03-php-wasm-node.md @@ -0,0 +1,642 @@ +--- +title: php-wasm/node +slug: /developers/local-development/php-wasm-node +description: WordPress Playground trae PHP con WebAssembly a Node.js para ejecución del lado del servidor, procesamiento de datos y pruebas sin instalación nativa. +--- + +# Usando WordPress Playground en Node.js + +Como un proyecto WebAssembly, también puedes usar WordPress Playground en Node.js. + +Si necesitas control de bajo nivel sobre la compilación WebAssembly de PHP subyacente, echa un vistazo al [paquete @php-wasm/node](https://npmjs.org/@php-wasm/node) que incluye el runtime WebAssembly de PHP. Este paquete está en el núcleo de todas las herramientas de WordPress Playground para Node.js. + +Consulta la [lista completa](/api/node) de Clases, Funciones, Interfaces y Alias de Tipos. + +## WebAssembly PHP para Node.js + +Este paquete incluye binarios WebAssembly de PHP y la API JavaScript optimizada para Node.js. Utiliza el sistema de archivos del host directamente y puede acceder a la red si conectas un proxy WS personalizado. + +### Uso básico + +```javascript +import { PHP } from '@php-wasm/universal'; +import { loadNodeRuntime } from '@php-wasm/node'; + +const php = new PHP(await loadNodeRuntime('8.3')); +const output = await php.runStream({ + code: '', +}); +console.log(await output.stdoutText); +``` + +## Casos de uso + +### Ejecución PHP del lado del servidor + +Puedes ejecutar scripts PHP en entornos Node.js sin instalar PHP nativamente. Perfecto para: + +- Pipelines CI/CD que necesitan ejecución PHP +- Microservicios que ocasionalmente necesitan funcionalidad PHP +- Herramientas de desarrollo y scripts de construcción + +### Procesamiento y transformación de datos + +Puedes procesar y manipular datos usando el rico ecosistema de PHP: + +- Transformación de datos CSV, JSON y XML +- Operaciones de base de datos SQLite sin dependencias externas +- Creación y extracción de archivos (ZIP, TAR) +- Procesamiento y manipulación de imágenes + +### Renderización de plantillas y generación de contenido + +Puedes generar contenido dinámico usando plantillas PHP: + +- Renderización de plantillas de email +- Generación de informes HTML +- Generación de documentación +- Creación dinámica de archivos de configuración + +### Desarrollo y pruebas de APIs + +Puedes construir y probar endpoints de API: + +- Servidores de API simulados para pruebas +- Simulación de petición/respuesta +- Prototipado de endpoints de API +- Pruebas de integración para APIs PHP + +### Análisis y prueba de código PHP + +Puedes construir herramientas que analizan, hacen lint o prueban código PHP: + +- Herramientas de análisis estático +- Formateadores y validadores de código +- Ejecutores de pruebas unitarias +- Generadores de documentación + +### Integración de código heredado + +Puedes hacer puente entre los ecosistemas PHP y JavaScript: + +- Migrar aplicaciones PHP incrementalmente +- Usar bibliotecas PHP en proyectos JavaScript +- Ejecutar PHP junto con frameworks JavaScript modernos +- Proporcionar compatibilidad hacia atrás + +### Plataformas educativas + +Puedes crear entornos de aprendizaje PHP interactivos: + +- Tutoriales de codificación en línea +- Documentación interactiva +- Playgrounds y sandboxes de código +- Desafíos de programación + +### Herramientas de desarrollo WordPress + +Puedes construir utilidades de desarrollo WordPress: + +- Validadores de plugin/tema +- Alternativas al WordPress CLI +- Inicialización de entorno de desarrollo +- Herramientas de prueba automatizada + +## Demos prácticas + +### Demo 1: Operaciones en el sistema de archivos + +Ejecuta scripts PHP que interactúan con el sistema de archivos: + +```javascript +import { PHP } from '@php-wasm/universal'; +import { loadNodeRuntime } from '@php-wasm/node'; + +const php = new PHP(await loadNodeRuntime('8.3')); + +// Crear estructura de directorios +php.mkdir('/app/data'); + +// Escribir archivo de configuración +await php.writeFile( + '/app/config.json', + JSON.stringify({ + app: 'MyApp', + version: '1.0.0', + debug: true, + }) +); + +// Crear y ejecutar script PHP que lee la configuración +await php.writeFile( + '/app/index.php', + `` +); + +const result = await php.runStream({ scriptPath: '/app/index.php' }); +console.log(await result.stdoutText); +``` + +### Demo 2: Operaciones de base de datos SQLite + +Usa la extensión SQLite de PHP para almacenamiento de datos: + +```javascript +import { PHP } from '@php-wasm/universal'; +import { loadNodeRuntime } from '@php-wasm/node'; + +const php = new PHP(await loadNodeRuntime('8.3')); + +// Crear directorio para la base de datos +php.mkdir('/data'); + +// Crear base de datos, insertar datos y consultar +const result = await php.runStream({ + code: `exec('CREATE TABLE IF NOT EXISTS users ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + name TEXT NOT NULL, + email TEXT UNIQUE NOT NULL, + created_at DATETIME DEFAULT CURRENT_TIMESTAMP +)'); + +// Insertar datos de ejemplo +$stmt = $db->prepare('INSERT INTO users (name, email) VALUES (?, ?)'); +$users = [ + ['Alice Johnson', 'alice@example.com'], + ['Bob Smith', 'bob@example.com'], + ['Charlie Davis', 'charlie@example.com'] +]; + +foreach ($users as $user) { + $stmt->bindValue(1, $user[0]); + $stmt->bindValue(2, $user[1]); + $stmt->execute(); +} + +// Consultar datos +echo "All Users:\\n"; +echo str_repeat('-', 50) . "\\n"; +$results = $db->query('SELECT * FROM users ORDER BY name'); +while ($row = $results->fetchArray(SQLITE3_ASSOC)) { + echo "ID: {$row['id']} | {$row['name']} ({$row['email']})\\n"; +} + +$db->close(); +?>`, +}); + +console.log(await result.stdoutText); + +// El archivo de base de datos persiste en el sistema de archivos virtual +const dbExists = await php.fileExists('/data/app.db'); +console.log('\nDatabase persisted:', dbExists); +``` + +### Demo 3: Procesamiento de archivos subidos (archivos ZIP) + +Procesa archivos ZIP usando la extensión Libzip de PHP: + +```javascript +import { PHP } from '@php-wasm/universal'; +import { loadNodeRuntime } from '@php-wasm/node'; + +const php = new PHP(await loadNodeRuntime('8.3')); + +// Crear archivos de ejemplo +php.mkdir('/uploads'); +await php.writeFile('/uploads/readme.txt', 'This is a sample text file'); +await php.writeFile('/uploads/data.json', JSON.stringify({ name: 'Test', version: '1.0' })); + +// Crear, procesar y extraer archivo ZIP +const result = await php.runStream({ + code: `open('/uploads/archive.zip', ZipArchive::CREATE); +$zip->addFromString('readme.txt', file_get_contents('/uploads/readme.txt')); +$zip->addFromString('data.json', file_get_contents('/uploads/data.json')); +$zip->addFromString('info.txt', 'Created with PHP WASM'); +$zip->close(); + +echo "ZIP archive created successfully\\n\\n"; + +// Leer y mostrar contenido del archivo +$zip->open('/uploads/archive.zip'); +echo "Archive Contents:\\n"; +echo str_repeat('=', 50) . "\\n"; + +for ($i = 0; $i < $zip->numFiles; $i++) { + $stat = $zip->statIndex($i); + $size = round($stat['size'] / 1024, 2); + echo sprintf("%-40s %10s KB\\n", $stat['name'], $size); +} + +// Extraer archivos +$zip->extractTo('/uploads/extracted/'); +$zip->close(); + +echo "\\nExtracted successfully to /uploads/extracted/\\n"; + +// Listar archivos extraídos +echo "\\nExtracted Files:\\n"; +$files = new RecursiveIteratorIterator( + new RecursiveDirectoryIterator('/uploads/extracted/') +); +foreach ($files as $file) { + if ($file->isFile()) { + echo " " . $file->getPathname() . "\\n"; + } +} +?>`, +}); + +console.log(await result.stdoutText); +``` + +### Demo 4: Patrón de petición/respuesta HTTP + +Simula comportamiento de servidor web con manejadores de peticiones: + +```javascript +import { PHP } from '@php-wasm/universal'; +import { loadNodeRuntime } from '@php-wasm/node'; + +const php = new PHP(await loadNodeRuntime('8.3')); + +// Configurar un endpoint de API simple +await php.mkdir('/www/api'); +await php.writeFile( + '/www/api/users.php', + ` [ + ['id' => 1, 'name' => 'John Doe'], + ['id' => 2, 'name' => 'Jane Smith'] + ] + ]); + break; + + case 'POST': + $name = $input['name'] ?? 'Unknown'; + echo json_encode([ + 'success' => true, + 'user' => [ + 'id' => 3, + 'name' => $name + ], + 'message' => "User $name created" + ]); + break; + + default: + http_response_code(405); + echo json_encode(['error' => 'Method not allowed']); +} +?>` +); + +// Hacer petición GET +const getResponse = await php.runStream({ + scriptPath: '/www/api/users.php', + env: { + REQUEST_METHOD: 'GET', + SERVER_NAME: 'localhost', + SERVER_PORT: '80', + }, +}); +console.log('GET Response:', await getResponse.stdoutText); + +// Hacer petición POST +const postResponse = await php.runStream({ + scriptPath: '/www/api/users.php', + env: { + REQUEST_METHOD: 'POST', + SERVER_NAME: 'localhost', + SERVER_PORT: '80', + }, + body: JSON.stringify({ name: 'Alice Wonder' }), +}); +console.log('\\nPOST Response:', await postResponse.stdoutText); +``` + +### Demo 5: Motor de renderización de plantillas + +Usa PHP como motor de plantillas para contenido dinámico: + +```javascript +import { PHP } from '@php-wasm/universal'; +import { loadNodeRuntime } from '@php-wasm/node'; + +const php = new PHP(await loadNodeRuntime('8.3')); + +// Crear directorio de plantillas +php.mkdir('/templates'); + +// Crear plantilla +await php.writeFile( + '/templates/email.php', + ` + + + + + +
+

Welcome, !

+
+
+

Thank you for registering with .

+

Your account details:

+
    +
  • Email:
  • +
  • Member Since:
  • +
+

You now have access to the following features:

+
    + +
  • + +
+
+ + +` +); + +// Renderizar plantilla con datos +const templateData = { + name: 'Priya Sharma', + email: 'priya@example.com', + appName: 'MyAwesomeApp', + timestamp: Math.floor(Date.now() / 1000), + features: ['Dashboard Access', 'API Integration', 'Premium Support', 'Custom Branding'], +}; + +// Pasar datos a la plantilla vía variables de entorno o archivos +await php.writeFile('/template-data.json', JSON.stringify(templateData)); + +const result = await php.runStream({ + code: ``, +}); + +console.log(await result.stdoutText); +// Ahora tienes HTML renderizado que puede enviarse por email o guardarse +``` + +### Demo 6: Ejecución de código en tiempo real y streaming + +Procesa la salida de PHP conforme se genera: + +```javascript +import { PHP } from '@php-wasm/universal'; +import { loadNodeRuntime } from '@php-wasm/node'; + +const php = new PHP(await loadNodeRuntime('8.3')); + +await php.writeFile( + '/stream-demo.php', + `` +); + +// Ejecutar script PHP +const streamedResponse = await php.runStream({ + scriptPath: '/stream-demo.php', +}); + +console.log('Processing PHP output:\n'); +console.log(await streamedResponse.stdoutText); +console.log(`\nExit code: ${streamedResponse.exitCode}`); +``` + +## Patrones de integración + +### Patrón 1: Middleware Express.js + +Integra procesamiento PHP en una aplicación Express.js: + +```TypeScript +import express from 'express'; +import { PHP } from '@php-wasm/universal'; +import { loadNodeRuntime } from '@php-wasm/node'; + +const app = express(); +const php = new PHP(await loadNodeRuntime('8.3')); + +// Middleware de ejecución PHP +app.use('/php', async (req, res, next) => { + try { + const phpScript = req.query.script || 'index.php'; + const result = await php.runStream({ + scriptPath: `/www/${phpScript}`, + env: { + REQUEST_METHOD: req.method, + QUERY_STRING: new URLSearchParams( + req.query as Record + ).toString(), + REQUEST_URI: req.url, + }, + }); + + res.send(await result.stdoutText); + } catch (error) { + next(error); + } +}); + +app.listen(3000, () => { + console.log('Server with PHP support running on port 3000'); +}); +``` + +### Patrón 2: Pruebas automatizadas + +Crea pruebas automatizadas para código PHP: + +```TypeScript +import { describe, it, expect, beforeAll } from '@jest/globals'; +import { PHP } from '@php-wasm/universal'; +import { loadNodeRuntime } from '@php-wasm/node'; + +describe('PHP Functions', () => { + let php: PHP; + + beforeAll(async () => { + php = new PHP(await loadNodeRuntime('8.3')); + }); + + it('should calculate sum correctly', async () => { + const result = await php.run({ + code: ``, + }); + + expect(result.text).toBe('8'); + }); + + it('should handle JSON operations', async () => { + const input = { name: 'Test', value: 42 }; + const result = await php.run({ + code: ` $input, + 'doubled' => $input['value'] * 2 + ]; + echo json_encode($output); + ?>`, + }); + + const output = JSON.parse(result.text); + expect(output.doubled).toBe(84); + }); +}); +``` + +### Patrón 3: Integración con herramientas de construcción + +Usa en scripts de construcción con otras herramientas Node.js: + +```javascript +import { PHP } from '@php-wasm/universal'; +import { loadNodeRuntime } from '@php-wasm/node'; +import fs from 'fs/promises'; + +async function generateDocumentation() { + const php = new PHP(await loadNodeRuntime('8.3')); + + // Crear directorio de salida + php.mkdir('/output'); + + // Generar documentación + const result = await php.runStream({ + code: ``, + }); + + console.log(await result.stdoutText); + + // Extraer documentación generada de vuelta al sistema de archivos Node.js + await fs.mkdir('./docs', { recursive: true }); + const summaryContent = await php.readFileAsText('/output/summary.md'); + await fs.writeFile('./docs/summary.md', summaryContent); + + console.log('Documentation saved to ./docs/summary.md'); +} + +generateDocumentation().catch(console.error); +``` + +## Características avanzadas + +### Trabajando con variables de entorno + +```javascript +import { PHP } from '@php-wasm/universal'; +import { loadNodeRuntime } from '@php-wasm/node'; + +const php = new PHP(await loadNodeRuntime('8.3')); + +const result = await php.runStream({ + code: '', + env: { + CUSTOM_VAR: 'Hello from Node.js!', + }, +}); + +console.log(await result.stdoutText); +``` + +### Manejo de errores + +```javascript +import { PHP } from '@php-wasm/universal'; +import { loadNodeRuntime } from '@php-wasm/node'; + +const php = new PHP(await loadNodeRuntime('8.3')); + +try { + const result = await php.runStream({ + code: '', + }); + + const stdout = await result.stdoutText; + const stderr = await result.stderrText; + + console.log('stdout:', stdout); + console.log('stderr:', stderr); + + if (stderr) { + console.error('PHP produced errors:', stderr); + } +} catch (error: any) { + console.error('JavaScript Error:', error.message); +} +``` + +## Consideraciones de rendimiento + +- **Reutiliza instancias PHP**: Crear una nueva instancia PHP es costoso. Reutiliza la misma instancia cuando sea posible. +- **Operaciones por lotes**: Agrupa múltiples operaciones de archivos juntas en lugar de ejecutar scripts separados. +- **Gestión de memoria**: Los archivos grandes pueden impactar el rendimiento. Considera streaming para grandes conjuntos de datos. +- **Caché**: Almacena en caché scripts PHP compilados y datos accedidos frecuentemente. diff --git a/packages/docs/site/i18n/pt-BR/docusaurus-plugin-content-docs/current/developers/05-local-development/03-php-wasm-node.md b/packages/docs/site/i18n/pt-BR/docusaurus-plugin-content-docs/current/developers/05-local-development/03-php-wasm-node.md index 74280541d4..52891a028e 100644 --- a/packages/docs/site/i18n/pt-BR/docusaurus-plugin-content-docs/current/developers/05-local-development/03-php-wasm-node.md +++ b/packages/docs/site/i18n/pt-BR/docusaurus-plugin-content-docs/current/developers/05-local-development/03-php-wasm-node.md @@ -1,30 +1,642 @@ --- title: php-wasm/node slug: /developers/local-development/php-wasm-node +description: WordPress Playground traz PHP com WebAssembly para Node.js para execução do lado do servidor, processamento de dados e testes sem instalação nativa. --- - - # Usando WordPress Playground no Node.js - - Como um projeto WebAssembly, você também pode usar o WordPress Playground no Node.js. - +Se você precisa de controle de baixo nível sobre a compilação WebAssembly do PHP subjacente, dê uma olhada no [pacote @php-wasm/node](https://npmjs.org/@php-wasm/node) que inclui o runtime WebAssembly do PHP. Este pacote está no centro de todas as ferramentas WordPress Playground para Node.js. -Se você precisa de controle de baixo nível sobre a compilação WebAssembly do PHP subjacente, dê uma olhada no pacote [`@php-wasm/node`](https://npmjs.org/@php-wasm/node) que inclui o runtime WebAssembly do PHP. Este pacote está no centro de todas as ferramentas WordPress Playground para Node.js. +Consulte a [lista completa](/api/node) de Classes, Funções, Interfaces e Aliases de Tipo. - +## WebAssembly PHP para Node.js -:::info **Referência da API** +Este pacote inclui binários WebAssembly do PHP e a API JavaScript otimizada para Node.js. Ele usa o sistema de arquivos do host diretamente e pode acessar a rede se você conectar um proxy WS customizado. - +### Uso básico -Consulte a [lista completa](/api/node) de Classes, Funções, Interfaces e Aliases de Tipo. +```javascript +import { PHP } from '@php-wasm/universal'; +import { loadNodeRuntime } from '@php-wasm/node'; + +const php = new PHP(await loadNodeRuntime('8.3')); +const output = await php.runStream({ + code: '', +}); +console.log(await output.stdoutText); +``` + +## Casos de uso + +### Execução PHP do lado do servidor + +Você pode executar scripts PHP em ambientes Node.js sem instalar PHP nativamente. Perfeito para: + +- Pipelines CI/CD que precisam de execução PHP +- Microserviços que ocasionalmente precisam de funcionalidade PHP +- Ferramentas de desenvolvimento e scripts de build + +### Processamento e transformação de dados + +Você pode processar e manipular dados usando o rico ecossistema do PHP: + +- Transformação de dados CSV, JSON e XML +- Operações de banco de dados SQLite sem dependências externas +- Criação e extração de arquivos (ZIP, TAR) +- Processamento e manipulação de imagens + +### Renderização de templates e geração de conteúdo + +Você pode gerar conteúdo dinâmico usando templates PHP: + +- Renderização de templates de email +- Geração de relatórios HTML +- Geração de documentação +- Criação dinâmica de arquivos de configuração + +### Desenvolvimento e teste de APIs + +Você pode construir e testar endpoints de API: + +- Servidores de API mock para testes +- Simulação de requisição/resposta +- Prototipagem de endpoints de API +- Testes de integração para APIs PHP + +### Análise e teste de código PHP + +Você pode construir ferramentas que analisam, fazem lint ou testam código PHP: + +- Ferramentas de análise estática +- Formatadores e validadores de código +- Executores de testes unitários +- Geradores de documentação + +### Integração de código legado + +Você pode fazer a ponte entre os ecossistemas PHP e JavaScript: + +- Migrar aplicações PHP incrementalmente +- Usar bibliotecas PHP em projetos JavaScript +- Executar PHP junto com frameworks JavaScript modernos +- Fornecer compatibilidade retroativa + +### Plataformas educacionais + +Você pode criar ambientes de aprendizado PHP interativos: + +- Tutoriais de codificação online +- Documentação interativa +- Playgrounds e sandboxes de código +- Desafios de programação + +### Ferramentas de desenvolvimento WordPress + +Você pode construir utilitários de desenvolvimento WordPress: + +- Validadores de plugin/tema +- Alternativas ao WordPress CLI +- Inicialização de ambiente de desenvolvimento +- Ferramentas de teste automatizado + +## Demos práticas + +### Demo 1: Operações no sistema de arquivos + +Execute scripts PHP que interagem com o sistema de arquivos: + +```javascript +import { PHP } from '@php-wasm/universal'; +import { loadNodeRuntime } from '@php-wasm/node'; + +const php = new PHP(await loadNodeRuntime('8.3')); + +// Criar estrutura de diretórios +php.mkdir('/app/data'); + +// Escrever arquivo de configuração +await php.writeFile( + '/app/config.json', + JSON.stringify({ + app: 'MyApp', + version: '1.0.0', + debug: true, + }) +); + +// Criar e executar script PHP que lê a configuração +await php.writeFile( + '/app/index.php', + `` +); + +const result = await php.runStream({ scriptPath: '/app/index.php' }); +console.log(await result.stdoutText); +``` + +### Demo 2: Operações de banco de dados SQLite + +Use a extensão SQLite do PHP para armazenamento de dados: + +```javascript +import { PHP } from '@php-wasm/universal'; +import { loadNodeRuntime } from '@php-wasm/node'; + +const php = new PHP(await loadNodeRuntime('8.3')); + +// Criar diretório para o banco de dados +php.mkdir('/data'); + +// Criar banco de dados, inserir dados e consultar +const result = await php.runStream({ + code: `exec('CREATE TABLE IF NOT EXISTS users ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + name TEXT NOT NULL, + email TEXT UNIQUE NOT NULL, + created_at DATETIME DEFAULT CURRENT_TIMESTAMP +)'); + +// Inserir dados de exemplo +$stmt = $db->prepare('INSERT INTO users (name, email) VALUES (?, ?)'); +$users = [ + ['Alice Johnson', 'alice@example.com'], + ['Bob Smith', 'bob@example.com'], + ['Charlie Davis', 'charlie@example.com'] +]; + +foreach ($users as $user) { + $stmt->bindValue(1, $user[0]); + $stmt->bindValue(2, $user[1]); + $stmt->execute(); +} + +// Consultar dados +echo "All Users:\\n"; +echo str_repeat('-', 50) . "\\n"; +$results = $db->query('SELECT * FROM users ORDER BY name'); +while ($row = $results->fetchArray(SQLITE3_ASSOC)) { + echo "ID: {$row['id']} | {$row['name']} ({$row['email']})\\n"; +} + +$db->close(); +?>`, +}); + +console.log(await result.stdoutText); + +// Arquivo do banco de dados persiste no sistema de arquivos virtual +const dbExists = await php.fileExists('/data/app.db'); +console.log('\nDatabase persisted:', dbExists); +``` + +### Demo 3: Processamento de arquivos enviados (arquivos ZIP) + +Processe arquivos ZIP usando a extensão Libzip do PHP: + +```javascript +import { PHP } from '@php-wasm/universal'; +import { loadNodeRuntime } from '@php-wasm/node'; + +const php = new PHP(await loadNodeRuntime('8.3')); + +// Criar arquivos de exemplo +php.mkdir('/uploads'); +await php.writeFile('/uploads/readme.txt', 'This is a sample text file'); +await php.writeFile('/uploads/data.json', JSON.stringify({ name: 'Test', version: '1.0' })); + +// Criar, processar e extrair arquivo ZIP +const result = await php.runStream({ + code: `open('/uploads/archive.zip', ZipArchive::CREATE); +$zip->addFromString('readme.txt', file_get_contents('/uploads/readme.txt')); +$zip->addFromString('data.json', file_get_contents('/uploads/data.json')); +$zip->addFromString('info.txt', 'Created with PHP WASM'); +$zip->close(); + +echo "ZIP archive created successfully\\n\\n"; + +// Ler e exibir conteúdo do arquivo +$zip->open('/uploads/archive.zip'); +echo "Archive Contents:\\n"; +echo str_repeat('=', 50) . "\\n"; + +for ($i = 0; $i < $zip->numFiles; $i++) { + $stat = $zip->statIndex($i); + $size = round($stat['size'] / 1024, 2); + echo sprintf("%-40s %10s KB\\n", $stat['name'], $size); +} + +// Extrair arquivos +$zip->extractTo('/uploads/extracted/'); +$zip->close(); + +echo "\\nExtracted successfully to /uploads/extracted/\\n"; + +// Listar arquivos extraídos +echo "\\nExtracted Files:\\n"; +$files = new RecursiveIteratorIterator( + new RecursiveDirectoryIterator('/uploads/extracted/') +); +foreach ($files as $file) { + if ($file->isFile()) { + echo " " . $file->getPathname() . "\\n"; + } +} +?>`, +}); + +console.log(await result.stdoutText); +``` + +### Demo 4: Padrão de requisição/resposta HTTP + +Simule comportamento de servidor web com manipuladores de requisição: + +```javascript +import { PHP } from '@php-wasm/universal'; +import { loadNodeRuntime } from '@php-wasm/node'; + +const php = new PHP(await loadNodeRuntime('8.3')); + +// Configurar um endpoint de API simples +await php.mkdir('/www/api'); +await php.writeFile( + '/www/api/users.php', + ` [ + ['id' => 1, 'name' => 'John Doe'], + ['id' => 2, 'name' => 'Jane Smith'] + ] + ]); + break; + + case 'POST': + $name = $input['name'] ?? 'Unknown'; + echo json_encode([ + 'success' => true, + 'user' => [ + 'id' => 3, + 'name' => $name + ], + 'message' => "User $name created" + ]); + break; + + default: + http_response_code(405); + echo json_encode(['error' => 'Method not allowed']); +} +?>` +); + +// Fazer requisição GET +const getResponse = await php.runStream({ + scriptPath: '/www/api/users.php', + env: { + REQUEST_METHOD: 'GET', + SERVER_NAME: 'localhost', + SERVER_PORT: '80', + }, +}); +console.log('GET Response:', await getResponse.stdoutText); + +// Fazer requisição POST +const postResponse = await php.runStream({ + scriptPath: '/www/api/users.php', + env: { + REQUEST_METHOD: 'POST', + SERVER_NAME: 'localhost', + SERVER_PORT: '80', + }, + body: JSON.stringify({ name: 'Alice Wonder' }), +}); +console.log('\\nPOST Response:', await postResponse.stdoutText); +``` + +### Demo 5: Motor de renderização de templates + +Use PHP como um motor de templates para conteúdo dinâmico: + +```javascript +import { PHP } from '@php-wasm/universal'; +import { loadNodeRuntime } from '@php-wasm/node'; + +const php = new PHP(await loadNodeRuntime('8.3')); + +// Criar diretório de templates +php.mkdir('/templates'); + +// Criar template +await php.writeFile( + '/templates/email.php', + ` + + + + + +
+

Welcome, !

+
+
+

Thank you for registering with .

+

Your account details:

+
    +
  • Email:
  • +
  • Member Since:
  • +
+

You now have access to the following features:

+
    + +
  • + +
+
+ + +` +); + +// Renderizar template com dados +const templateData = { + name: 'Priya Sharma', + email: 'priya@example.com', + appName: 'MyAwesomeApp', + timestamp: Math.floor(Date.now() / 1000), + features: ['Dashboard Access', 'API Integration', 'Premium Support', 'Custom Branding'], +}; + +// Passar dados para o template via variáveis de ambiente ou arquivos +await php.writeFile('/template-data.json', JSON.stringify(templateData)); + +const result = await php.runStream({ + code: ``, +}); + +console.log(await result.stdoutText); +// Agora você tem HTML renderizado que pode ser enviado por email ou salvo +``` + +### Demo 6: Execução de código em tempo real e streaming + +Processe a saída do PHP conforme ela é gerada: + +```javascript +import { PHP } from '@php-wasm/universal'; +import { loadNodeRuntime } from '@php-wasm/node'; + +const php = new PHP(await loadNodeRuntime('8.3')); + +await php.writeFile( + '/stream-demo.php', + `` +); + +// Executar script PHP +const streamedResponse = await php.runStream({ + scriptPath: '/stream-demo.php', +}); + +console.log('Processing PHP output:\n'); +console.log(await streamedResponse.stdoutText); +console.log(`\nExit code: ${streamedResponse.exitCode}`); +``` + +## Padrões de integração + +### Padrão 1: Middleware Express.js + +Integre processamento PHP em uma aplicação Express.js: + +```TypeScript +import express from 'express'; +import { PHP } from '@php-wasm/universal'; +import { loadNodeRuntime } from '@php-wasm/node'; + +const app = express(); +const php = new PHP(await loadNodeRuntime('8.3')); + +// Middleware de execução PHP +app.use('/php', async (req, res, next) => { + try { + const phpScript = req.query.script || 'index.php'; + const result = await php.runStream({ + scriptPath: `/www/${phpScript}`, + env: { + REQUEST_METHOD: req.method, + QUERY_STRING: new URLSearchParams( + req.query as Record + ).toString(), + REQUEST_URI: req.url, + }, + }); + + res.send(await result.stdoutText); + } catch (error) { + next(error); + } +}); + +app.listen(3000, () => { + console.log('Server with PHP support running on port 3000'); +}); +``` + +### Padrão 2: Testes automatizados + +Crie testes automatizados para código PHP: + +```TypeScript +import { describe, it, expect, beforeAll } from '@jest/globals'; +import { PHP } from '@php-wasm/universal'; +import { loadNodeRuntime } from '@php-wasm/node'; + +describe('PHP Functions', () => { + let php: PHP; + + beforeAll(async () => { + php = new PHP(await loadNodeRuntime('8.3')); + }); + + it('should calculate sum correctly', async () => { + const result = await php.run({ + code: ``, + }); + + expect(result.text).toBe('8'); + }); + + it('should handle JSON operations', async () => { + const input = { name: 'Test', value: 42 }; + const result = await php.run({ + code: ` $input, + 'doubled' => $input['value'] * 2 + ]; + echo json_encode($output); + ?>`, + }); + + const output = JSON.parse(result.text); + expect(output.doubled).toBe(84); + }); +}); +``` + +### Padrão 3: Integração com ferramentas de build + +Use em scripts de build com outras ferramentas Node.js: + +```javascript +import { PHP } from '@php-wasm/universal'; +import { loadNodeRuntime } from '@php-wasm/node'; +import fs from 'fs/promises'; + +async function generateDocumentation() { + const php = new PHP(await loadNodeRuntime('8.3')); + + // Criar diretório de saída + php.mkdir('/output'); + + // Gerar documentação + const result = await php.runStream({ + code: ``, + }); + + console.log(await result.stdoutText); + + // Extrair documentação gerada de volta para o sistema de arquivos Node.js + await fs.mkdir('./docs', { recursive: true }); + const summaryContent = await php.readFileAsText('/output/summary.md'); + await fs.writeFile('./docs/summary.md', summaryContent); + + console.log('Documentation saved to ./docs/summary.md'); +} + +generateDocumentation().catch(console.error); +``` + +## Recursos avançados + +### Trabalhando com variáveis de ambiente + +```javascript +import { PHP } from '@php-wasm/universal'; +import { loadNodeRuntime } from '@php-wasm/node'; + +const php = new PHP(await loadNodeRuntime('8.3')); + +const result = await php.runStream({ + code: '', + env: { + CUSTOM_VAR: 'Hello from Node.js!', + }, +}); + +console.log(await result.stdoutText); +``` + +### Tratamento de erros + +```javascript +import { PHP } from '@php-wasm/universal'; +import { loadNodeRuntime } from '@php-wasm/node'; + +const php = new PHP(await loadNodeRuntime('8.3')); + +try { + const result = await php.runStream({ + code: '', + }); + + const stdout = await result.stdoutText; + const stderr = await result.stderrText; + + console.log('stdout:', stdout); + console.log('stderr:', stderr); -::: + if (stderr) { + console.error('PHP produced errors:', stderr); + } +} catch (error: any) { + console.error('JavaScript Error:', error.message); +} +``` -import PHPWASMNode from '@php-wasm/node/\README.md'; +## Considerações de desempenho - +- **Reutilize instâncias PHP**: Criar uma nova instância PHP é custoso. Reutilize a mesma instância quando possível. +- **Operações em lote**: Agrupe múltiplas operações de arquivo juntas em vez de executar scripts separados. +- **Gerenciamento de memória**: Arquivos grandes podem impactar o desempenho. Considere streaming para grandes conjuntos de dados. +- **Cache**: Faça cache de scripts PHP compilados e dados acessados frequentemente.