Temas del curso php
Introducción a PHPPHP es un lenguaje rápido pese a ser interpretado, multiplataforma y dispone de una gran cantidad de bibliotecas para el desarrollo de aplicaciones Web.
Está basado en herramientas de software libre (Apache, MySQL, etc.), es decir, no hay que pagarlas; además proporciona los mecanismos para poder trabajar con casi cualquier base de datos (sea software libre o no) y servidor web.
Cuando pedimos a nuestro servidor web una página PHP, que no es sino un programa PHP que genera una página HTML, el servidor le pasa la página al interprete PHP y es el resultado lo que se le envía al cliente.
El interprete de PHP permite ser compilado y utilizado como un CGI. De esta forma cualquier servidor web que soporte CGI podría ejecutar páginas PHP. Nosotros en este tutorial lo vamos a usar como un módulo de Apache, la ventaja es que obtenemos una velocidad de ejecución bastante superior, asi como un consumo menor de recursos. En el caso de tener PHP instalado como un módulo del servidor Apache, este hereda todas las características del servidor.
PHP se contruyó para ser utilizado conjuntamente con la base de datos MySQL, pero actualmente soporta la mayoría de bases de datos (Oracle, Informix, ODBC, SQl Server, etc.). Nosotros utilizaremos MySQL, porque la interacción entre PHP y MySQL funciona a la perfección y además es software libre.
Debido a que PHP has sido diseñado de forma modular y sencilla, hay multitud de bibliotecas entre ellas destacamos el soporte para:
Acceso de servidores IMAP y POP3
Envío de correo con SMTP
Acceso de servidores FTP
Acceso a SNMP para gestión de redes y equipos
HTTP a nivel de socket
Generación dinámica de documentos PDF
Análisis y procesamiento de documentos XML y XSLT
Corrector de ortografía
Expresiones regulares de Perl
Utilización de clases Java o módulos .NET
Creación de animaciones Flash usando PHP
Instalación PHP, MySQL y APACHE en distribución LINUX y/o MICROSOFT.
Como instalar Apache + PHP + MySQL sin usar instaladores
La gran mayoria usa Appserv, Xampp o algunos de esos paquetes pre-configurados para novatos.
El proposito de este tutorial es explicar paso a paso como armar tu propio paquete a partir de los .zip sin usar instalador.
De esta manera te aseguras de tener la ultima version de los tres componentes basicos.
Probado en Windows 2000, XP y Vista.
Descargar los 3 .zip:
www.apachelounge.com/download/
Apache Lounge toma el codigo fuente desde http://httpd.apache.org/ y lo compila usando Visual C++ 2008
windows.php.net/download/
PHP es bien conocido por ser el mejor lenguaje interpretado en el servidor para hacer webs dinamicas.
Descargar el que dice "VC9 x86 Thread Safe"
dev.mysql.com/downloads/
Hace falta explicar las virtudes de este motor de base de datos SQL ?
Descargar la version estable "Community Server"
Visual C++ 2008 Redistributable Package
Por si no lo tenias instalado. Necesario para la version compilada por Apache Lounge que descargamos mas arriba.
Descomprimiendo todo en su lugar:
La idea es tener 3 carpetas:
c:\apache
c:\php
c:\mysql
Descomprimir el contenido del .zip de Apache en "c:\apache"
Mover el contenido de la carpeta "c:\apache\Apache2" a "c:\apache"
Borrar la carpeta "Apache2" (porque quedo vacia)
Borrar todos los .txt sueltos en "c:\apache" (no es realmente necesario). Quedaria asi:
Descomprimir el .zip de PHP en C:\php
Descomprimir el .zip de MySQL en C:\ y renombrar la carpeta generada (por ej. mysql-5.0.67-win32) a c:\mysql
Configurar Apache Webserver:
Abrir "c:\apache\conf\httpd.conf" (conviene asociarlo con el Bloc de notas) y editar esto:
ServerRoot "c:/apache"
DocumentRoot "c:/apache/htdocs"
ServerAdmin lucianoaibar@telpin.com.ar
ServerName miservidor.com:80
<Directory "c:/apache/htdocs">
Options FollowSymLinks
AllowOverride None
Order allow,deny
Allow from all
</Directory>
<IfModule dir_module>
DirectoryIndex index.php index.html index.htm
</IfModule>
ErrorDocument 401 "<html><body bgcolor=#000000><center><h1><br><font face='Verdana' color=#FF0000><b>ACCESO DENEGADO</b></center></font></html>"
ErrorDocument 403 http://miservidor.com/
ErrorDocument 404 "<html><h1>Archivo no encontrado.</html>"
ErrorDocument 500 "<html><h1>ups!... un error.</html>"
Instalar Apache Webserver como servicio de Windows ejecutando:
c:\apache\bin\httpd.exe -k install
Configurar PHP:
Renombrar c:\php\php.ini-production a php.ini
Copiar c:\php\php5ts.dll a c:\apache\bin
Editar php.ini asi:
doc_root = c:\apache\htdocs
extension_dir = c:\php\ext
enable_dl = on <-- Habilita la funcion dl() para cargar extensiones en tiempo de ejecucion
Habilitar las extensiones necesarias eliminando el signo ";" anterior a "extension=php_..."
No es necesario usar la funcion dl() si de habilita una extension en php.ini
Aclaracion: algunas extensiones necesitan de DLLs en C:\WINDOWS\SYSTEM32
Por ejemplo habilitar soporte para MySQL:
extension=php_mysql.dll
De nuevo editar "c:\apache\conf\httpd.conf" y agregar:
LoadModule php5_module "c:/php/php5apache2_2.dll"
PHPIniDir "c:/php"
... y buscar "<IfModule mime_module>". Abajo agregar:
AddType application/x-httpd-php .php
Configurar MySQL:
Renombrar c:\mysql\my-medium.ini a c:\mysql\my.ini
Agregar esto arriba del todo dentro del archivo c:\mysql\my.ini :
[mysqld]
basedir=C:\\mysql
datadir=C:\\mysql\\data
Copiar c:\mysql\bin\libmysql.dll a c:\apache\bin
Instalar MySQL como servicio de Windows ejecutando:
Inicio automatico: mysqld.exe --install MySQL --defaults-file=C:\mysql\my.ini
Inicio manual: mysqld.exe --install-manual MySQL --defaults-file=C:\mysql\my.ini
Iniciar MySQL ejecutando:
NET START MySQL
Asignar clave al usuario "root" ejecutando:
c:\mysql\bin\mysql.exe -u root
UPDATE mysql.user SET Password = PASSWORD('1234') WHERE User = 'root';
FLUSH PRIVILEGES;
exit;
Terminando:
Agregar al inicio de Windows un acceso directo a "c:\apache\bin\ApacheMonitor.exe"
Te queda un iconito a la derecha, pegado a la hora, que te sirve para iniciar el Webserver
Verificar por errores leyendo el archivo "c:\apache\logs\error.log"
y empeza a rellenar c:\apache\htdocs con tu web ^^
------------------------------------------------------------------------------------
Pasos previos a la programación. Instalación del modulo PHP en distintos servidores web.
Como todo lenguaje de lado servidor, PHP, requiere de la instalación de un servidor en nuestro PC para poder trabajar en local. Este modo de trabajo resulta a todas luces más práctico que colgar los archivos por FTP en el servidor y ejecutarlos desde Internet.
Así pues, antes comenzar a crear nuestros programas en PHP, es necesario:
- Convertir nuestro ordenador en un servidor. Esto se hace instalando uno de los varios servidores disponibles para el sistema operativo de nuestra máquina.
- Introducir en nuestro servidor los archivos que le permitirán la comprensión del PHP. Estos archivos pueden ser descargados, en su versión más actual, de la página oficial de PHP.
Para conocer la forma de instalar PHP sobre cada servidor de cada sistema operativo podemos dirigirnos al apartado de documentación de la página oficial de PHP donde disponemos de un manual en HTML de rápida consulta y un enorme manual en PDF de casi 1000 páginas traducido al castellano donde explican minuciosamente y entre otras cosas, los pasos a seguir para cada caso particular. De todos modos, nosotros vamos a ofrecer algunas ayudas para configurar PHP en los sistemas más habituales.
La elección de vuestro programa servidor tendrá mucho que ver con el sistema operativo que tengáis corriendo en vuestro ordenador. Estas serían algunas posibilidades de sistemas opertativos y soluciones que funcionan bien.
Windows 95/98
Si estáis trabajando en Windows 95 o Windows 98 y para desarrolladores principiantes, podría ser recomendable utilizar el servidor Personal Web Ser. En este caso necesitaríais:
- Personal Web Server de Microsoft como servidor el cual os sirve además para el aprendizaje en ASP. Tenéis una guía de instalación y configuración en esta misma web.
- Una instalación autoextraible de la versión más reciente de PHP que, además de tardar menos en descargarse, os guiará paso a paso en el proceso de instalación. Esta versión no incluye todas las funcionalidades de PHP, pero os servirá para aprender hasta un buen nivel.
Hay que señalar que, para el caso de PHP en PWS, además de todo lo dicho en capítulo de instalación, es importante al crear el directorio virtual permitir la ejecución de scripts validando la caja correspondiente.
En Windows 95/98 también podremos utilizar el servidor Apache y puede que sea una opción todavía más completa que la de utilizar PWS. A continuación explicamos más sobre ello.
Windows ME y XP Home edition
No hemos probado PHP en estas plataformas, pero en principio no tienen compatibilidad con Personal Web Server, por lo que deberíamos decantarnos por otro servidor.
Conceptos básicos:
La primera vez que una variable se utiliza en un ámbito de aplicación , se crea automáticamente . Después de esto isset es cierto . En el punto en el que se crea también recibe un tipo de acuerdo con el contexto .<? php
$ a_bool = true , / / un valor lógico
$ a_str = ' foo' , / / una cadena
? >
Si se utiliza sin haber sido dado un valor, entonces se uninitalized y recibe el valor predeterminado para el tipo . Los valores predeterminados son los valores _empty_ . Por ejemplo Booleanos defecto en false, enteros y carrozas por defecto a cero , cadenas a la cadena vacía '' , arreglos para el conjunto vacío .
Una variable puede ser probado por vacío con vacío ();
<? php
$ a = 0 ; / / Este isset , pero está vacía
? >
Variables no definidas también están vacías .
<? php
empty ($ buque); / / devuelve true . También está desarmado $ buque.
? >
Todo lo anterior se aplica a los elementos de la matriz también.
<? php
$ item = array ();
/ / Ahora isset ( $ item ) devuelve true. Pero isset ( $ item [' unicornio ']) es falsa .
/ / empty ( $ item ) es cierto , y así está vacío ( $ item [' unicornio ']
$ item [' unicornio '] ='';
/ / Ahora isset ( $ item [' unicornio '] ) es verdadera . Y empty ($ elemento) es falso.
/ / Pero vacío ( $ item [' unicornio ']) sigue siendo cierto ;
$ item [' unicornio '] = 'Pink unicorn " ;
/ / isset ( $ item [' unicornio ']) sigue siendo cierto . Y empty ($ elemento) sigue siendo falsa.
/ / Pero ahora vacío ( $ item [' unicornio ']) es falso ;
? >
Para arrays , esto es importante porque el acceso a elemento de la matriz inexistente puede provocar errores, es posible que desee probar matrices y elementos de la matriz de la existencia con isset antes de usarlos.
hasta
abajo
4 maurizio dot domba en pu t - dot com dot hace HR2 años
Si usted necesita para comprobar el usuario introduce el valor de una variable convención de nomenclatura adecuada PHP es necesario agregar ^ para la expresión regular anterior para que la expresión regular debe ser " ^ [a- zA - Z_ \ x7f - \ xff ] [a- zA -Z0 -9_ \ x7f - \ xff ] * .
ejemplo
<? php
$ name = " 20011aa " ;
if (! preg_match ('/ [a- zA - Z_ \ x7f - \ xff ] [a- zA -Z0 -9_ \ x7f - \ xff ] * / ', $ nombre) )
echo $ nombre ' . no es un nombre válido de variable PHP ' ;
más
echo $ nombre ' . PHP es válido nombre de la variable ' ;
? >
Salidas: 2011aa es válida PHP nombre de la variable
pero
<? php
$ name = " 20011aa " ;
if (! preg_match ('/ ^ [a- zA - Z_ \ x7f - \ xff ] [a- zA -Z0 -9_ \ x7f - \ xff ] * / ', $ nombre) )
echo $ nombre ' . no es un nombre válido de variable PHP ' ;
más
echo $ nombre ' . PHP es válido nombre de la variable ' ;
? >
Salidas: 2011aa PHP no es un nombre de variable válido
hasta
abajo
0 hace Edoxile3 años
Al querer cambiar dos variables de contenido, puede utilizar el operador XOR :
<? PHP
$ a = 5 ;
$ b = 3 ;
/ / Por favor, recuerda el orden de estos, ya que es importante para el resultado.
$ a ^ = $ b ;
$ b = $ a ^ ;
$ a ^ = $ b ;
echo $ a.PHP_EOL $ b . ;
/ * Imprime :
3
5
* /
? >
Esto también funciona en las cuerdas , pero no va a trabajar en arrays y objetos , por lo que para ellos tendrás que utilizar la función de serializar () de antes de la operación y el unserialize () después .
hasta
abajo
0 php en richardneill dot hace Org1 meses
Tenga en cuenta que "$ 1" no es un nombre de variable. PHP trata , literalmente , incluso cuando se está entre comillas dobles. Por ejemplo :
$ frutas = " apple" ;
echo " Esta fruta cuesta $ $ 1" ;
Esto es especialmente notable cuando se usa $ 1, $ 2, etc dentro de las consultas parametrizadas en SQL .
Tipos de variables
Estructuras de control (if, for, do/while, foreach, etc.)/dd>Expresiones regulares
Tipos de Operadores
Funciones
Variables Predefinidas
PHP proporciona una gran cantidad de variables predefinidas a cualquier script que se ejecute. Muchas de éstas, sin embargo, no pueden ser completamente documentadas ya que dependen del servidor que esté corriendo, la versión y configuración de dicho servidor, y otros factores. Algunas de estas variables no estarán disponibles cuando se ejecute PHP desde la línea de comandos. Para obtener una lista de estas variables, por favor vea la sección sobre Variables Predefinidas Reservadas.
Advertencia
A partir de PHP 4.2.0, el valor predeterminado de la directiva PHP register_globals es off (desactivada). Este es un cambio importante en PHP. Tener register_globals off afecta el conjunto de variables predefinidas disponibles en el sistema. Por ejemplo, para obtener DOCUMENT_ROOT se usará $_SERVER['DOCUMENT_ROOT'] en vez de $DOCUMENT_ROOT ó$_GET['id'] de la URL http://www.example.com/test.php?id=3 en lugar de $id ó $_ENV['HOME'] en lugar de $HOME.
Para más información sobre este cambio, puede consultar el apartado de configuración sobre register_globals, el capítulo sobre seguridad Usando "Register Globals" , asi como los anuncios de lanzamiento de PHP » 4.1.0 y » 4.2.0
El uso de las variables reservadas predefinidas en PHP, como las matrices superglobales es recomendable.
A partir de PHP 4.1.0, PHP ofrece un conjunto adicional de matrices predefinidas que contienen variables del servidor web, el entorno y entradas del usuario. Estas nuevas matrices son un poco especiales porque son automáticamente globales. Por esta razón, son conocidas a menudo como "superglobales". Las superglobales se mencionan más abajo; sin embargo para una lista de sus contenidos y más información sobre variables predefinidas en PHP, por favor consulte la sección Variables predefinidas reservadas. Asimismo, podrá notar cómo las antiguas variables predefinidas ($HTTP_*_VARS) todavía existen. A partir de PHP 5.0.0, los arrays de variables predefinidas de tipo long de PHP se pueden desactivar con la directiva register_long_arrays .
Nota: Variables variables
Las superglobales no pueden ser usadas como variables variables al interior de funciones o métodos de clase.
Nota:
Aún cuando las superglobales y HTTP_*_VARS pueden existir al mismo tiempo; estas variables no son idénticas, así que modificar una no cambia la otra.
Si ciertas variables no son definidas en variables_order, las matrices PHP predefinidas asociadas a estas, estarán vacías.
yarco dot w at gmail dot com
7 years ago
And you should know
$_POST is not a reference of $HTTP_POST_VARS
So, if you change $_POST, there are no change to $HTTP_POST_VARS.
LouisGreen at pljg dot freeserve dot co dot uk
10 years ago
If you require access to Predefined Variables in different PHP/ servers versions and don't wish to mess about with how you access them, this little snippet of code might help you:
function fn_http_vars_access() {
global $GET_VARS, $POST_VARS, $COOKIE_VARS, $SESSION_VARS, $SERVER_VARS, $ENV_VARS;
$parser_version = phpversion();
if ($parser_version <= "4.1.0") {
$GET_VARS = $GET_VARS;
$POST_VARS = $POST_VARS;
$COOKIE_VARS = $COOKIE_VARS;
$SESSION_VARS = $HTTP_SESSION_VARS;
$SERVER_VARS = $HTTP_SERVER_VARS;
$ENV_VARS = $HTTP_ENV_VARS;
}
if ($parser_version >= "4.1.0") {
$GET_VARS = $_GET;
$POST_VARS = $_POST;
$COOKIE_VARS = $_COOKIE;
$SESSION_VARS = $_SESSION;
$SERVER_VARS = $_SERVER;
$ENV_VARS = $_ENV;
}
}
fn_http_vars_access();
joker at vip dot hr
10 years ago
If anyone of you have a problem with uploading files with globals off here is the solution... just add this to the top of the code:
reset ($_FILES);
while (list ($key, $val) = each ($_FILES)) {
${$key}=$_FILES[$key]['tmp_name'];
while (list ($key1, $val1) = each ($val)) {
${$key."_".$key1}=$_FILES[$key][$key1];
}
}
Daniel
Anonymous
8 years ago
php.net uses this
// Backward compatible array creation. After this point, the
// PHP 4.1.0+ arrays can be used to access variables coming
// from outside PHP. But it should be noted that these variables
// are not necessarily superglobals, so they need to be global-ed!
if (!isset($_SERVER))
{
$_GET = &$HTTP_GET_VARS;
$_POST = &$HTTP_POST_VARS;
$_ENV = &$HTTP_ENV_VARS;
$_SERVER = &$HTTP_SERVER_VARS;
$_COOKIE = &$HTTP_COOKIE_VARS;
$_REQUEST = array_merge($_GET, $_POST, $_COOKIE);
}
$PHP_SELF = $_SERVER['PHP_SELF'];
LouisGreen at pljg dot freeserve dot co dot uk
10 years ago
It seems that when you wish to export a varible, you can do it as return $varible, return an array(), or globalise it. If you return something, information for that varible can only travel one way when the script is running, and that is out of the function.
function fn() {
$varible = "something";
return $variable;
}
echo fn();
OR
$newvariable = fn();
Although if global was used, it creates a pointer to a varible, whether it existed or not, and makes whatever is created in the function linked to that global pointer. So if the pointer was global $varible, and then you set a value to $varible, it would then be accessible in the global scope. But then what if you later on in the script redefine that global to equal something else. This means that whatever is put into the global array, the information that is set in the pointer, can be set at any point (overiden). Here is an example that might make this a little clearer:
function fn1() {
global $varible; // Pointer to the global array
$varible = "something";
}
fn1();
echo $varible; // Prints something
$varible = "12345";
echo $varible; // Prints 12345
function fn2() {
global $varible; // Pointer to the global array
echo $varible;
}
fn2(); // echos $varible which contains "12345"
Basically when accessing the global array, you can set it refer to something already defined or set it to something, (a pointer) such as varible you plan to create in the function, and later possibly over ride the pointer with something else.
Good Liam
10 years ago
Warning:
If you use dynamic variables in a local scope, the variable doesn't "know" when it should be a superglobal. An example will help elucidate this:
function Example($Variable_Name='_POST') {
print_r($$Variable_Name);
} // End Example
This would print out
NULL
To use a dynamic variable to reference a superglobal, you have to declare the value (not the name) as a global:
function WorkingExample($Variable_Name='_POST') {
global $$Variable_Name;
print_r($$Variable_Name);
} // End WorkingExample()
This would print out the contents of your $_POST variable.
This threw me when I first tried it, but it makes sense, in a way.
Anonymous
10 years ago
i just noticed that the free web server i'm running my scripts on still only knows the deprecated variable names (i.e. it uses $HTTP_POST_VARS instead of $_POST). to make scripts work both on updated servers and servers that are a bit out of date, i now use:
$variablename=(isset($_POST["variablename"])) ? $_POST["variablename"] : $HTTP_POST_VARS["variablename"];
johnphayes at gmail dot com
7 years ago
I haven't found it anywhere else in the manual, so I'll make a note of it here - PHP will automatically replace any dots ('.') in an incoming variable name with underscores ('_'). So if you have dots in your incoming variables, e.g.:
example.com/page.php?chuck.norris=nevercries
you can not reference them by the name used in the URI:
//INCORRECT
echo $_GET['chuck.norris'];
instead you must use:
//CORRECT
echo $_GET['chuck_norris'];
dompody [at] gmail [dot] com
8 years ago
To urbanheroes:
version_compare() is only in PHP version 4.1.0 and up. This completely negates your function, since if the version is less than 4.1.0 it will generate an error anyway. The better solution is to do what is stated in the post above yours:
<?phpif (!isset($_SERVER))
{
$_GET = &$HTTP_GET_VARS;
$_POST = &$HTTP_POST_VARS;
$_ENV = &$HTTP_ENV_VARS;
$_SERVER = &$HTTP_SERVER_VARS;
$_COOKIE = &$HTTP_COOKIE_VARS;
$_REQUEST = array_merge($_GET, $_POST, $_COOKIE);
}?>
Include that before everything else in your script and it will fix the flaw.
mike at dbeat dot com
12 years ago
If you're running PHP as a shell script, and you want to use the argv and argc arrays to get command-line arguments, make sure you have register_argc_argv = on. If you're using the 'optimized' php.ini, this defaults to off.
pinkgothic at gmail dot com
6 years ago
Dealing with "superglobals" and functions is not as straightforward as it may seem when you're doing plenty manipulations.
For example:
<?php
function some_other_method() {
echo $_REQUEST['id'];
}
function some_method() {
$_REQUEST['id'] = 440;
some_other_method();
}?>
Calling some_method() will cause a warning-level error by PHP informing you that "id" is not set in some_other_method(). However, if you instead use:
<?php
$_REQUEST['id'] = 0;
function some_other_method() {
echo $_REQUEST['id'];
}
function some_method() {
$_REQUEST['id'] = 440;
some_other_method();
}?>
Then the script will echo 440.
In consequence, if you manually attempt to add keys to the superglobals, those keys *aren't* automatically superglobal. The above example isn't very sensible, of course, but this can be a huge gotcha if you're juggling user data between functions and you're unwittingly being forced to work inside a function (e.g. via PHP include in TYPO3).
Unfortunately, global $_REQUEST['id'] won't save you, either - it causes a parse error - nor will a global $_REQUEST change anything after you've set the keys... consequently making it hard to conviniently 'hack' outdated scripts by making them believe they're still running in a different environment.
The only "solution" to this issue is to use parameters.
root at mantoru dot de
5 years ago
To tokie at hanmail dot net: You took that out of context -- it is merely a recommendation.
If your variables_order setting does not contain "E", $_ENV is still useful. Every call to getenv will be "cached" in $_ENV, so you can do this:
<?php// variables_order = GPCSvar_dump(isset($_ENV['PATH'])); // bool(false)getenv('PATH');var_dump(isset($_ENV['PATH'])); // bool(true)?>
For some reason, it does not work with with own environment variables. The above example with PHP_TEST instead of PATH would fail (if it is set via putenv).
holger at doessing dot net
6 years ago
On the subject of permalinks and queries:
Say, you use an inexpensive subdomain of (e.g.) www.nice.net, thus www.very.nice.net, and that the domain owner has simply placed a frame at this particular location, linking to the actual address (ugly and subject-to-change) of your site.
Consequently, the actual site URI and various associated hashes and query strings are not immediately visible to the user. Sometimes this is useful, but it also makes bookmarking/permalinking impossible (the browser will only bookmark the static address in the top frame).
However, as far as the query strings go, there is workaround. Instead of providing users with permalinks to the actual URI (e.g. prtcl://weird.and.ugly/~very/ugly.php?stuff=here; may even be subject to change), I provide them with this: prtcl://www.very.nice.net?stuff=here.
In brief, I then use the following code to re-populate the $_GET array:
if (isset($_SERVER['HTTP_REFERER'])) { // If set, this page is running in a frame
$uri = parse_url($_SERVER['HTTP_REFERER']); // grab URI of parent frame
$querystring = ($uri['query']) ? $uri['query'] : false; // grab the querystring
if ($querystring) {
$vars = explode('&', $querystring); // cut into individual statements
foreach ($vars as $varstring) { // populate $_GET
$var = explode('=', $varstring);
if (count($var) == 2) $_GET[$var[0]] = $var[1];
}
} // no, nothing to report from the parent frame
} // no, not using a parent frame today...
If the actual host address is ever changed, users entering the frame (with the nicer address) will be using the new (and ugly) URI, but this way the old query strings will be available to the new address also. The users will never again be bothered by you moving to another neighborhood.
myfirstname dot barros at gmail dot com
8 years ago
vars in $_REQUEST are *not* a reference to the respective $_POST and $_GET and $_COOKIE ones.
Consider:
http://site.com/index.php?avar=abc
index.php:
<?php
$_GET['avar'] = 'b';print_r($_GET); print('<br>');print_r($_REQUEST);?>
output:
Array ( [avar] => 'b' )
Array ( [avar] => 'abc' )
marcbender_AT_mail_DOT_com
9 years ago
-Security issue-
In response to lopez at yellowspace,
You provided a method for executing potentially unsafe code:
> function safeEval($evalcode) {
> unset($GLOBALS);
> unset($_ENV);
> // unset any other superglobal...
> return eval($evalcode);
> }
Your method, though clever, won't work. The problem is the way that PHP handles function scope. If $evalcode contains a function declaration, and runs that function, the "unset"s will be effectively useless inside the body of that function.
Try running the above code with $evalcode set as follows:
<?php
$evalcode='f();
function f() {
$GLOBALS["_SERVER"] = "compromised";
}';?>
Then print $_SERVER and see what you get.
Another problem is that the "global" directive will always grant access to global variables. Try this one:
<?php
$evalcode='global $a;
$a = "compromised";';?>
$a will of course be changed at the global level. I don't know if it's supposed to work this way, but on my system (PHP 4.3.4) you can do the same to any superglobal by importing it using "global".
As far as I can tell, there is NO way to execute potentially unsafe code without a lot of risk. With the sloppy way that PHP deals with function scope etc., there isn't much hope that it ever will be. What we'd need is (at least):
- a way to disable the "global" directive (restrictive eval).
- a way to shut off any write-access to superglobals within untrusted functions.
The first wouldn't be too hard to implement. The second, on the other hand, is practically impossible IMHO.
jk at ricochetsolutions dot com
7 years ago
here is a one line snippet to do the same as DD32's func
@preg_replace(
"/(?i)([a-z0-9_]+)\/([a-z0-9_]+)\/?/e",
'$_GET[\'$1\'] = "$2";',
((isset($_SERVER['PATH_INFO'])) ? $_SERVER['PATH_INFO'] : '')
);
may be faster, it may not ;o
DD32=theonly_DD32[&]yahoo.com.au
7 years ago
I have this function in my main files, it allows for easier SEO for some pages without having to rely on .htaccess and mod_rewrite for some things.
<?php
function long_to_GET(){
/**
* This function converts info.php/a/1/b/2/c?d=4 TO
* Array ( [d] => 4 [a] => 1 [b] => 2 [c] => )
**/
if(isset($_SERVER['PATH_INFO']) && $_SERVER['PATH_INFO'] != ''){
//Split it out.
$tmp = explode('/',$_SERVER['PATH_INFO']);
//Remove first empty item
unset($tmp[0]);
//Loop through and apend it into the $_GET superglobal.
for($i=1;$i<=count($tmp);$i+=2){ $_GET[$tmp[$i]] = $tmp[$i+1];}
}
}?>
Its probably not the most efficient, but it does the job rather nicely.
DD32
Graeme Jefferis
8 years ago
I find this sort of thing consistently useful for dealing with superglobals in safety and comfort.
<?phpforeach ($_POST as $key => $value)
{
switch ($key)
{
case "submitted_var_1":
case "submitted_var_2":
case "submitted_var_3":
$$key = $value; break;
case "dangerous_var":
$value = do_something_special_with($value);
$$key = $value;
break;
}
}?>
kasey at cornerspeed dowt com
9 years ago
I have a few points to note to (debabratak at softhome dot net). Firstly, extracting all your variables from the global variable arrays is rather cumbersome and possibly unsafe. This causes longer run times, and wastes more memory. Then, your script is starting the session before it parses the superglobals. Bad things can happen because of this:
<?php
// user sent a GET header with key = secret_access, val = true, so
echo $_GET["secret_access"]; // output: trueecho $secret_access; // output:
session_start();
// in previous logic, you set session variable $secret_access = false
echo $_SESSION["secret_access"]; // output: falseecho $secret_access; // output: false
extract_globals(); // Globals put into "normal" variables
echo $_GET["secret_access"]; // output: trueecho $_SESSION["secret_access"]; // output: falseecho $secret_access; // output: true
// VARIABLES ARE COMPROMISED!
// DO NOT USE $secret_access !
// USE $_SESSION["secret_access"] instead !!!
?>
Secondly, I would like to point out the fact that all $_POST, $_GET, and $_COOKIE variables are intrinsically unsafe anyway. Users can create their own scripts in the language of their choosing (PHP, ASP, JSP, etc.) that generate those headers to send to your PHP program via socket connections. PHP cannot determine that these headers are any less valid than the ones sent by a web browser, so it parses them and places them in the $_POST, $_GET, or $_COOKIE variables.
The best practice is to use $_SESSION variables to validate the user before making any decisions based on form data. e.g.:
<?php
session_start();
if (isset($_SESSION["valid"]))
{
// all your program decisions and database interactions can go here
if (isset($_POST["button_name"]))
{
...
}
...
}
elseif (isset($_POST["submit_login"]))
{
if (($_POST["username"] == "foo") AND ($_POST["password"] == "bar"))
{
$_SESSION["valid"] = true;
...
}
else
{
session_unset();
session_destroy();
$error_msg = "Invalid username or password";
$result_page = "login.php";
}
}
elseif (isset($logoff))
{
session_unset();
session_destroy();
$success_msg = "You have logged off successfully";
$result_page = "login.php";
}
else
{
session_unset();
session_destroy();
$result_page = "login.php";
}
require ($result_page);?>
Session variables are orders of magnitude harder to compromise than POST, GET, and COOKIE data, since the server keeps track of session id's, and the session id is unique to each client and somewhat randomly generated. If security is an ultimate concern, then you need to use SSL in case your traffic can be sniffed (since the session cookie is passed plain text to the client).
In summary, extracting out all the superglobals to normal variable names is not a good idea for reasons of security and ambiguity, not to mention wasted CPU cycles. For private applications (ones that you don't want just anyone to be able to access), the only ways you can prevent malicious access is to 1) use sessions to ensure that the user is valid (for that page), and 2) use SSL-encryption to prevent session-hijacking.
Kasey
in reply to:
--------------------------------------------------------------
debabratak at softhome dot net
14-Mar-2003 12:59
After having register_globals = off, I am using the following piece of code to get all the variables created for me. I have put this code in a separate file and just make it require_once() on top of every page.
session_start();
$ArrayList = array("_GET", "_POST", "_SESSION", "_COOKIE", "_SERVER");
foreach($ArrayList as $gblArray)
{
$keys = array_keys($$gblArray);
foreach($keys as $key)
{
$$key = trim(${$gblArray}[$key]);
}
}
This pulls out all the possible variables for me, including the predefined variables, so I can keep coding the old style. Note that, this code does not handle the $_FILE.
Hope this helps someone.
bryan at nolifeline dot com
9 years ago
to marcbender at mail dot com
unset the globals
use a preg_replace ( pattern: |\;[^\;]*$i[^\;]*\;|Uis, replacement: ";", where $i is the name of any function/variable you wish to prevent access to.) on the code-to-be-evaled. ideas are "global", "fopen", "mysql_connect", etc. You know, anything that you wouldn't want to give a hyperactive 13 year old access to.
execute the code.
mark at pitchpipe dot org
9 years ago
I had always mistakenly assumed that superglobal $_COOKIE (while preferred) was identical to the outdated $HTTP_COOKIE_VARS. However, if you assign:
$_COOKIE['destroyWorld'] = "true";
if (isset($HTTP_COOKIE_VARS['destroyWorld'])) {
$temp =& new Armeggedon();
$temp->pushRedButton();
}
then the world will be safe forever. Might throw off a newbie, or someone like me who was updating really old code bit-by-bit.
Anonymous
10 years ago
In reply to destes at ix dot netcom dot com dot nospam:
It's possible for a HTTP client to spoof HTTP_X_FORWARDED_FOR, and set it to a fake IP number. It's more secure to use this code and log BOTH the ip and the proxy ip.
if ($_SERVER["HTTP_X_FORWARDED_FOR"]) {
if ($_SERVER["HTTP_CLIENT_IP"]) {
$proxy = $_SERVER["HTTP_CLIENT_IP"];
} else {
$proxy = $_SERVER["REMOTE_ADDR"];
}
$ip = $_SERVER["HTTP_X_FORWARDED_FOR"];
} else {
if ($_SERVER["HTTP_CLIENT_IP"]) {
$ip = $_SERVER["HTTP_CLIENT_IP"];
} else {
$ip = $_SERVER["REMOTE_ADDR"];
}
}
echo "Your IP $ip<BR>\n";
if (isset($proxy)) {
echo "Your proxy IP is $proxy<BR>\n";
}
sendoshin[at]noodleroni[dot]com
8 years ago
There is one way to safely execute PHP code files without running the risk of compromising your own code. A prior note pointed out that the code being evaluated would still have access to globals using the global keyword. While this is a valid point, there's one other approach to be looked at - one which actually gives you much more ability than just unsetting some variable references. It's known as code parsing.
The specifics would be different and much more complex in a deployed site, but here's an extremely strip-down example of how to restrict access to global variables:
<?php
while ($x = stristr ($code_to_eval, "global")) {
$temp = substr ($code_to_eval, 1, $x-1);
$temp .= substr ($code_to_eval, stristr ($code_to_eval, ";", $x) + 1);
$code_to_eval = $temp;
}
$ret_val = eval ($code_to_eval);?>
Of course, that's just a rudimentary example, and a deployment version would have much more checking involved, but parsing the file before you eval it lets you remove any code you don't want to let run, thus making it as safe as your parsing rules.
fabrizio at bibivu dot com
6 years ago
theonly_DD32, I refined your function a little bit
<?php
function long_to_GET($PATH_INFO=''){
/**
* This function converts info.php/a/1/b/2/c?d=4 TO
* array ( [d] => 4 [a] => 1 [b] => 2 [c] => array ( [d] => 4 ) )
* got this function from http://php.net/GLOBALS
**/
if($PATH_INFO=='' && isset($_SERVER['PATH_INFO']) && $_SERVER['PATH_INFO'] != ''){
$PATH_INFO = $_SERVER['PATH_INFO'];
}
if($PATH_INFO != ''){
//Split it out.
$tmp = explode('/',$PATH_INFO);
//Remove first empty item
unset($tmp[0]);
//Loop through and apend it into the $_GET superglobal.
for($i=1;$i<=count($tmp);$i+=2){
if(strpos($tmp[$i],'?')!==false){
$tmp1 = explode('?',$tmp[$i]);
parse_str(isset($tmp1[1])?$tmp1[1]:'',$_GET[$tmp1[0]]);
$i--;
} else {
$_GET[$tmp[$i]] = isset($tmp[$i+1])?$tmp[$i+1]:'';
}
}
}
}
?>Funciones predefinidas
PHP con MySQL
Conexión
Consultas
Inserciones
Funciones
Sesiones
Formularios
Manejo de archivos
Librerías PHP más comunes (Gráficas, PDF, Excel, Email)
PHP OO
Clases y Objetos
Operadores de resolución de ámbito(::)
Constructores
Visibilidad
Herencia de objetos
Abstracción de clases
Sobrecarga
Iteración de objetos
Clonación de objetos
Comparación de objetos
Implicación de Tipos
Objetos y referencias
Serialización de objetos