🐘 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.

El Manifiesto Vanilla Mobile

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.Kie en 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):

PowerShell
irm https://phphone.xyz/install.ps1 | iex

En macOS / Linux:

Bash
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
composer create-project phphone/phphone mi-app

Flujo de Trabajo Paso a Paso

1. Crear un Proyecto Nuevo (Con CLI Oficial)

Terminal
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:

Terminal
phphone run

3. Personalizar Ícono y Pantalla de Carga (Splash)

Coloca tu icon.png y splash.png en la carpeta setup/ y ejecuta:

Terminal
phphone setup

4. Compilar para Producción (Release)

Genera el APK / AAB con cifrado AES-256 en RAM:

Terminal
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)

  1. Desarrollas y compilas tu frontend: Trabajas con tus fuentes TypeScript (.ts) o componentes y ejecutas tu comando de compilación (ej. npm run build o npx tsc) para que deposite el JavaScript (.js) y CSS resultante dentro de tu carpeta de assets (ej: src/js/app.js).
  2. Configuras el archivo .phphoneignore: Excluyes del empaquetador móvil todas las carpetas y archivos pesados que solo sirven para desarrollo en PC (como node_modules/ o fuentes TS).
  3. Ejecutas o compilas con Phphone: Corres phphone run o phphone 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:

.phphoneignore
# 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
Resultado: Apps de Menos de 20 MB

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:

JavaScript (app.js)
// 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:

CSS (style.css)
/* 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:

PHP (index.php)
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 / idstringSi se envía, reemplaza/actualiza la notificación previa (ideal para pedidos). Si se omite, se acumulan.
group / thread_idstringAgrupa múltiples mensajes bajo una misma tarjeta (Estilo WhatsApp/Gmail).
replyboolHabilita el botón y campo de texto *"Responder"* en la propia notificación.

Base de Datos SQLite y Persistencia

Entorno de Solo-Lectura en APKs

En Android de producción, el directorio __DIR__ es de solo lectura. Para guardar datos persistentes en SQLite, usa siempre la ruta escribible nativa:

PHP Helper
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:

JavaScript (Disparador)
// Iniciar demonio que consulta cada 60 segundos
window.Kie.startDaemon(JSON.stringify({ 
    taskName: 'sync_data', 
    interval: 60 
}));
PHP (src/daemon.php)
<?php
$task = $_GET['task'] ?? 'unknown';
// Tu lógica periódica aquí (ej: sincronizar base de datos)

Buenas Prácticas & Prevención de Errores

Regla de Oro: Evitar Zend Bailouts

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.

Limitación de Peticiones POST en Release

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)))