2010-08-16 18 views
8

Por lo tanto, no procedo de un gran fondo de PHP, y me preguntaba si en el código bien formado, uno debe usar los 'superglobals' directamente, p. en medio de alguna función decir $_SESSION['x'] = 'y'; o si, como yo suelo hacer con las variables, es mejor enviarlos como argumentos que se pueden utilizar a partir de ahí, por ejemplo:¿Está utilizando superglobals directamente bueno o malo en PHP?

class Doer { 
    private $sess; 
    public function __construct(&$sess) { 
     $this->sess =& $sess; 
    } 
} 

$doer = new Doer($_SESSION); 

y luego usar la versión Doer->sess de dentro de Doer y tal. (La ventaja de este método es que deja en claro que Doer usa $ _SESSION.)

¿Cuál es el enfoque de diseño de PHP aceptado para este problema?

+5

Mueva los datos que necesita a las variables, después de validarlos, ya que los datos allí son sospechosos hasta que se validen. –

+0

Su enfoque es poco común, y aliasing el superglobal en un atributo local podría confundir a los desarrolladores de código. Pero es ciertamente legal, y si su objeto lo utiliza o lo filtra (por ejemplo, un asistente de configuración) probablemente sea una buena idea. – mario

Respuesta

13

Me gusta envolver $_SESSION, $_POST, $_GET y $_COOKIE en estructuras OOP.

que utiliza este método para centralizar el código que se encarga de saneamiento y validación, todos los isset() controles necesarios, nonces, setcookie parámetros, etc. También permite código de cliente que sea más fácil de leer (y me da la ilusión de que es más fácil de mantener)

Puede ser difícil imponer el uso de este tipo de estructura, especialmente si hay varios codificadores. Con $_GET, $_POST y $_COOKIE (creo), su código de inicialización puede copiar los datos, luego destruir el superglobal. Tal vez un destructor inteligente podría hacer esto posible con $ _SESSION (borrar $ _SESSION en la carga, escríbalo en el destructor), aunque no lo he intentado.

No suelo utilizar ninguna de estas técnicas de aplicación. Después de acostumbrarme, ver $_SESSION en el código fuera de la clase de sesión parece extraño, y trabajo principalmente solo.

EDITAR
Aquí hay un código de cliente de ejemplo, en el caso de que ayuda a alguien. Estoy seguro de mirar a cualquiera de los principales marcos que le dará mejores ideas ...

$post = Post::load(); 
$post->numeric ('member_age'); 
$post->email ('member_email'); 
$post->match ('/regex/','member_field'); 
$post->required ('member_first_name','member_email'); 
$post->inSet ('member_status',array('unemployed','retired','part-time','full-time')); 
$post->money ('member_salary'); 
$post->register ('member_last_name'); // no specific requirements, but we want access 
if ($post->isValid()) 
{ 
    // do good stuff 
    $firstName = $post->member_first_name; 
} 
else 
{ 
    // do error stuff 
} 

Post y sus amigos todos se derivan de una clase base que implementa el código de validación núcleo, añadiendo su propia funcionalidad específica como la forma tokens, configuración de cookies de sesión, lo que sea.

Internamente, la clase contiene una colección de datos válidos que se extrae de $_POST a medida que se llaman los métodos de validación, luego los devuelve como propiedades usando el método __get mágico. Los campos fallidos no se pueden acceder de esta manera.Mis métodos de validación (excepto required) no fallan en los campos vacíos, y muchos de ellos usan func_get_args para permitirles operar en múltiples campos a la vez. Algunos de los métodos (como money) traducen automáticamente los datos en tipos de valores personalizados.

En el caso de error, tengo una manera de transformar los datos en un formato que se puede guardar en la sesión y se utiliza para completar previamente el formulario y resaltar los errores después de redirigir al formulario original.

Una forma de mejorar esto sería almacenar la información de validación en una clase de formulario que se utiliza para procesar la validación del formulario y la potencia del lado del cliente, así como para limpiar los datos después del envío.

+0

** ¡Dame! ** ¿Podrías publicar tus envoltorios OOP para las matrices de entrada? Estoy usando algo similar, y me gustaría contrastar el enfoque con algo comparable. – mario

+0

@mario: No puedo publicar el código, pero puedo elaborar un poco para que se hagan una idea. Voy a editar la respuesta ahora. – grossvogel

+1

eso está bien. Pero el mío está aquí para la comparación: https://sourceforge.net/p/php7framework/wiki/input/ - solo quería saber qué tipo de funciones de utilidad usa o qué filtros considera más útiles. – mario

-3

Esto no es un buen uso de PHP.

recibe $ _SESSION las variables directamente:

$id = $_SESSION['id']; 
$hash = $_SESSION['hash']; 

etc.

+1

Y obtenga un buen E_NOTICE si la variable no existe en la matriz ... -> -1 – ThiefMaster

+0

¿Cómo obtiene $ _SESSION de todos modos? – Aziz

0

No recomendaría en absoluto pasar superglobal por referencia. En su clase, no está claro que lo que está modificando es una variable de sesión. Además, tenga en cuenta que $ _SESSION está disponible en todas partes fuera de su clase. Desde el punto de vista orientado a objetos, es tan erróneo poder modificar una variable dentro de una clase desde fuera de esa clase modificando una variable que no está relacionada con la clase. Tener un atributo público se considera una mala práctica, incluso peor.

2

La modificación del contenido de los superglobales se considera una práctica deficiente. Si bien no hay nada realmente incorrecto, especialmente si el código está 100% bajo su control, puede provocar efectos secundarios inesperados, especialmente cuando se considera el código de fuente mixta. Por ejemplo, si haces algo como esto:

$_POST['someval'] = mysql_real_escape_string($_POST['someval']); 

se podría esperar que en todas partes PHP hace que 'someval' disponible también conseguiría cambiado, pero este no es el caso. La copia en $_REQUEST['someval'] no se modificará y seguirá siendo la versión original "insegura". Esto podría conducir a una vulnerabilidad de inyección involuntaria si realiza todo el escape en $ _POST, pero una biblioteca posterior usa $ _REQUEST y supone que ya se ha escapado.

Como tal, incluso si puede modificarlos, es mejor tratar los superglobales como de solo lectura. Si tiene que meterse con los valores, mantenga sus propias copias en paralelo y haga los envoltorios/métodos de acceso necesarios para mantener esa copia.

2

Sé que esta pregunta es antigua, pero me gustaría añadir una respuesta.

Las clases de Mario para manejar las entradas son increíbles.

Prefiero envolver los superglobales de alguna manera. Puede hacer que su código MUCHO más fácil de leer y conducir a un mejor mantenimiento.

Por ejemplo, hay un código en mi trabajo actual ¡Odio! Las variables de sesión se usan de forma tan exhaustiva que no se puede cambiar de forma realista la implementación sin afectar drásticamente a todo el sitio.

Por ejemplo,

Digamos que ha creado una clase de sesión específicos de su aplicación.

class Session 
{ 
    //some nice code 
} 

Se podría escribir algo como lo siguiente

$session = new Session(); 
if($session->isLoggedIn()) 
{ 
    //do some stuff 
} 

En oposición a esto

if($_SESSION['logged'] == true) 
{ 
    //do some stuff 
} 

Esto parece un poco trivial, pero es un gran problema para mí. Digamos que en algún momento en el futuro, decido que quiero cambiar el nombre del índice de 'logged' a 'loggedIn'.

Ahora tengo que ir a cada lugar de la aplicación que la variable de sesión se utiliza para cambiar esto. O bien, puedo dejarlo y encontrar de alguna manera para mantener ambas variables.

¿O qué pasa si quiero comprobar que ese usuario es un usuario administrador y que está conectado?Podría terminar revisando dos variables diferentes en la sesión para esto. Pero, en cambio, podría encapsularlo en un método y acortar mi código.

Esto ayuda a otros programadores que miran su código porque es más fácil de leer y no tienen que 'pensar' tanto cuando miran el código. Pueden ir al método y ver que solo hay UNA forma de tener un usuario conectado. También te ayuda porque si quisieras hacer que el 'conectado' fuera más complejo, solo tienes que ir a un lugar para cambiarlo en lugar de tratar de hacer hallazgos globales con tu IDE e intentar cambiarlo de esa manera.

De nuevo, este es un ejemplo trivial, pero dependiendo de cómo uses la sesión, esta ruta de usar métodos y clases para proteger el acceso podría hacer que tu vida sea mucho más fácil de vivir.

Cuestiones relacionadas