🐘 Documentación Oficial de Phphone
Phphone es un framework y compilador híbrido PHP-Nativo de alto rendimiento para Android, iOS y Desktop. Empaca un runtime completo de PHP 8.4 embebido dentro de las aplicaciones móviles, permitiendo ejecutar controladores, bases de datos locales (SQLite3) y lógica de negocio directamente en el procesador del teléfono sin depender de servidores en la nube.
Construye aplicaciones móviles nativas utilizando únicamente PHP 8.4, HTML5, CSS3 y JavaScript. Sin Flutter, sin React Native, sin Electron y sin dependencias pesadas.
Glosario de Términos
- Phphone: El framework y compilador global que orquesta todo el proyecto.
- Motor Kie (Kie Engine): El motor core en C++ que hospeda los binarios de PHP y el puente de comunicación JNI/Swift. Inyecta el objeto
window.Kieen JavaScript. - Dual WebView: Arquitectura que superpone dos navegadores: uno frontal transparente para la interfaz local y uno trasero para cargar webs externas sin bloqueos de seguridad.
- KieBridge: Canal de comunicación nativo entre JavaScript y el sistema operativo móvil.
Requisitos Previos
Dado que Phphone genera binarios nativos reales, necesitas las herramientas estándar de desarrollo instaladas en tu máquina:
- PHP 8.0+ en tu terminal (para ejecutar el CLI orquestador).
- Android Studio con Android SDK y un emulador configurado.
- Xcode (Solo en macOS) con las Command Line Tools activas para compilar hacia iOS.
Instalación del CLI Global
Instala el CLI de Phphone con un solo comando en tu terminal:
En Windows (PowerShell Administrador):
irm https://phphone.xyz/install.ps1 | iex
En macOS / Linux:
curl -sS https://phphone.xyz/install.sh | bash
Opción Alternativa (Vía Composer / Packagist):
Si ya tienes Composer instalado en tu máquina, puedes generar un proyecto directamente desde el repositorio central oficial de Packagist:
composer create-project phphone/phphone mi-app
Flujo de Trabajo Paso a Paso
1. Crear un Proyecto Nuevo (Con CLI Oficial)
phphone create "Mi Tienda" com.mitienda.app
cd mi-tienda
2. Probar con Hot Reload
Detecta automáticamente tu emulador o dispositivo conectado y recarga el código al guardar:
phphone run
3. Personalizar Ícono y Pantalla de Carga (Splash)
Coloca tu icon.png y splash.png en la carpeta setup/ y ejecuta:
phphone setup
4. Compilar para Producción (Release)
Genera el APK / AAB con cifrado AES-256 en RAM:
phphone build apk --release
Ecosistema Frontend (TypeScript, Vite) & .phphoneignore
Phphone te da total libertad de stack. Puedes programar usando TypeScript, React/JSX, Vue, Tailwind CSS, Vite o paquetes de Composer. Para que estos entornos modernos convivan de forma óptima con la compilación móvil, el ciclo se divide en 3 pasos:
1. Flujo de Trabajo con Bundlers (Vite / TypeScript / Webpack)
- Desarrollas y compilas tu frontend: Trabajas con tus fuentes TypeScript (
.ts) o componentes y ejecutas tu comando de compilación (ej.npm run buildonpx tsc) para que deposite el JavaScript (.js) y CSS resultante dentro de tu carpeta de assets (ej:src/js/app.js). - Configuras el archivo
.phphoneignore: Excluyes del empaquetador móvil todas las carpetas y archivos pesados que solo sirven para desarrollo en PC (comonode_modules/o fuentes TS). - Ejecutas o compilas con Phphone: Corres
phphone runophphone build apk --release. El compilador ignorará la basura de desarrollo y empaquetará únicamente el JavaScript limpio y el backend PHP.
2. El Archivo .phphoneignore (Preconfigurado de Fábrica)
Cada proyecto creado con phphone create ya incluye un archivo .phphoneignore en su raíz listo para usar. Puedes editarlo para agregar o remover reglas de exclusión personalizadas según las herramientas que utilices:
# Dependencias y Bundlers de Frontend
node_modules/
package.json
package-lock.json
vite.config.js
tsconfig.json
src_ts/
# Dependencias pesadas o pruebas
tests/
.git/
.idea/
.vscode/
*.log
Gracias a .phphoneignore, puedes usar las herramientas más modernas de JavaScript y CSS en tu máquina sin inflar el peso de la app móvil. Tu usuario final descarga un binario ultra-optimizado.
Navegador Nativo Oculto (Dual WebView)
Permite cargar pasarelas de pago o sitios externos sin problemas de CORS ni bloqueos de X-Frame-Options:
// 1. Activar navegador de fondo
window.Kie.setBrowserActive(true);
// 2. Cargar la URL deseada
window.Kie.loadUrl('https://google.com');
// 3. Volver el fondo transparente en CSS
document.body.style.backgroundColor = 'transparent';
Manejo del Notch y Safe Areas (CSS)
Para evitar que el contenido quede oculto detrás de la cámara frontal o la barra de gestos:
/* Header con padding adaptativo para el notch */
.header {
padding-top: env(safe-area-inset-top, 20px);
}
/* Barra inferior adaptada a gestos */
.bottom-nav {
padding-bottom: env(safe-area-inset-bottom, 20px);
}
/* Sensación táctil nativa */
body {
-webkit-user-select: none;
user-select: none;
-webkit-tap-highlight-color: transparent;
overscroll-behavior-y: none;
}
APIs Nativas de Hardware (Phphone\Device)
Accede directamente a los sensores y hardware del teléfono en PHP sin importar dependencias externas:
use Phphone\Device;
// Tomar fotografía en Base64
$foto = Device::camera();
// Obtener coordenadas GPS
$gps = Device::gps(); // ['lat' => 4.6097, 'lng' => -74.0817]
// Autenticación Biométrica (Face ID / Huella)
if (Device::authenticate("Confirma tu identidad")) {
Device::toast("Acceso Autorizado");
}
// Vibración Háptica
Device::vibrate(200);
// Llavero Seguro (Keychain / Keystore)
Device::secureWrite("token", "mi_secreto_123");
$token = Device::secureRead("token");
| Método PHP | Descripción | Retorno |
|---|---|---|
Device::camera() | Abre la cámara nativa y captura una foto. | string (Base64) |
Device::gps() | Obtiene coordenadas precisas de geolocalización. | array ['lat', 'lng'] |
Device::authenticate($msg) | Solicita validación por Face ID o huella. | bool |
Device::vibrate($ms) | Activa la respuesta háptica del motor de vibración. | void |
Device::toast($message) | Muestra un mensaje flotante nativo en pantalla. | void |
Device::notification($title, $body) | Despliega una notificación local inmediata. | void |
Device::getContacts() | Recupera la lista de contactos del dispositivo. | array |
Notificaciones Push (Firebase FCM)
Phphone incluye un motor unificado de notificaciones push. Controla el comportamiento desde el payload JSON de tu backend:
| Parámetro | Tipo | Efecto Nativo |
|---|---|---|
tag / id | string | Si se envía, reemplaza/actualiza la notificación previa (ideal para pedidos). Si se omite, se acumulan. |
group / thread_id | string | Agrupa múltiples mensajes bajo una misma tarjeta (Estilo WhatsApp/Gmail). |
reply | bool | Habilita el botón y campo de texto *"Responder"* en la propia notificación. |
Base de Datos SQLite y Persistencia
En Android de producción, el directorio __DIR__ es de solo lectura. Para guardar datos persistentes en SQLite, usa siempre la ruta escribible nativa:
function getDB() {
$dataDir = __DIR__ . '/../../data';
// Si estamos en APK de producción (Solo-Lectura)
if (!is_writable(__DIR__)) {
$temp = rtrim(sys_get_temp_dir(), '/\\');
$dataDir = (strpos($temp, 'cache') !== false)
? dirname($temp) . '/files/app_data'
: dirname($temp) . '/Documents/app_data';
}
if (!is_dir($dataDir)) @mkdir($dataDir, 0777, true);
$pdo = new PDO('sqlite:' . $dataDir . '/database.sqlite');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
return $pdo;
}
Tareas en Segundo Plano (Daemons)
Ejecuta tareas silenciosas de PHP en bucle usando servicios de primer plano nativos:
// Iniciar demonio que consulta cada 60 segundos
window.Kie.startDaemon(JSON.stringify({
taskName: 'sync_data',
interval: 60
}));
<?php
$task = $_GET['task'] ?? 'unknown';
// Tu lógica periódica aquí (ej: sincronizar base de datos)
Buenas Prácticas & Prevención de Errores
El motor PHP se mantiene vivo en memoria compartida. NUNCA uses exit; ni die();, ya que forzarán un cierre abrupto (crash) de la app móvil. Usa return o lanza excepciones dentro de bloques try/catch.
Debido a restricciones de seguridad del WebView de Android, las intercepciones de red destruyen el cuerpo de las peticiones POST. Para enviar datos de JS a PHP en local, envía tus datos codificados como JSON en peticiones GET:
fetch('api.php?data=' + encodeURIComponent(JSON.stringify(payload)))