2012-09-18 8 views
6

Estoy tratando de encontrar una manera de construir un sistema de anzuelo muy similar al que usa Drupal. Con Drupal puede simplemente nombrar una función de cierta manera y se invocará automáticamente como un gancho si el módulo está habilitado.¿Cómo construiría un sistema simple de php hook que funcione así?

He mirado las otras respuestas aquí en Stackoverflow, pero ninguna de ellas realmente da una respuesta de cómo construir este tipo de características en una aplicación PHP.

+0

¿Mirar Drupal y aplicar ingeniería inversa? –

+0

@Paul En realidad, he estado haciendo eso, pero Drupal tiene bastante más funcionalidad de la que realmente necesito, y no es muy claro lo que realmente está manejando el sistema Hook. –

Respuesta

2

No estoy familiarizado con el funcionamiento interno de Drupal, pero probablemente lo hace utilizando Reflexión:

http://php.net/manual/en/book.reflection.php

debería incluir la página PHP que contiene las funciones de gancho, a continuación, utilizar la reflexión para encontrar funciones o clases métodos que coinciden con una convención de nomenclatura determinada, luego guarde los punteros de función para llamar a esas funciones cuando corresponda (como los eventos en el ciclo de vida de un módulo).

+0

¿Por qué me rechazaron? – Dai

+0

Estoy leyendo la página que proporcionó, no estoy seguro de por qué alguien podría votar por usted sin dejar un comentario explicando. Gracias. –

3

Puede usar PHP get_defined_functions para obtener una serie de cadenas de nombres de funciones, luego filtrar esos nombres por algún formato predefinido.

Esta muestra de la documentación de PHP:

<?php 
function myrow($id, $data) 
{ 
    return "<tr><th>$id</th><td>$data</td></tr>\n"; 
} 

$arr = get_defined_functions(); 

print_r($arr); 
?> 

Salidas algo como esto:

Array 
(
    [internal] => Array 
     (
      [0] => zend_version 
      [1] => func_num_args 
      [2] => func_get_arg 
      [3] => func_get_args 
      [4] => strlen 
      [5] => strcmp 
      [6] => strncmp 
      ... 
      [750] => bcscale 
      [751] => bccomp 
     ) 

    [user] => Array 
     (
      [0] => myrow 
     ) 

) 

Es un poco una técnica incompleta en comparación con un sistema de ganchos más explícito, pero funciona.

+0

+1. Y con una nota al margen: también hay https://github.com/AOP-PHP/AOP que puede usar de forma complementaria a esto. De hecho, creo que en un diseño limpio, solo usaría programación orientada a aspectos, sin este truco con "funciones definidas", pero no creo que el OP sea tan avanzado. Sin embargo, es una buena idea para otros lectores. Necesita al menos un VPS para usar esto, ya que la extensión AOP no es parte de la distribución estándar. – Flavius

8

Así es como lo hace drupal y cómo puede hacerlo. Usar la concatenación de cadenas con la convención de nombres. Con function_exists() y call_user_func_array() debe estar todo listo.

Estas son las dos funciones drupal internos que hacen el truco (module.inc)

function module_invoke() { 
    $args = func_get_args(); 
    $module = $args[0]; 
    $hook = $args[1]; 
    unset($args[0], $args[1]); 
    $function = $module .'_'. $hook; 
    if (module_hook($module, $hook)) { 
    return call_user_func_array($function, $args); 
    } 
} 

function module_hook($module, $hook) { 
    return function_exists($module .'_'. $hook); 
} 

Por lo tanto, sólo es necesario invocar

module_invoke('ModuleName','HookName', $arg1, $arg2, $arg3); 

que finalmente llamar

ModuleName_HookName($arg1,$arg2,$arg3); 
+0

No sé por qué se modificó, yo también, así que le di un voto positivo. – Dai

0

¿Por qué no solo funciona la función de existir? El desarrollador podría nombrar la función de una cierta manera, y los códigos de enlace simplemente comprueban que existen y luego llamarlos

Cuestiones relacionadas