3

Como sabemos, hay elementos que cambian según los sistemas operativos.

Algunos casos típicos:

  • El salto de línea
  • El separador de rutas de archivos
  • El separador de directorios
  • El directorio del usuario actual (home)

Si en código PHP yo quiero expresar cualquiera de estos elementos, el resultado puede no ser igual en todos los sistemas operativos.

Entonces, ¿cómo escribir código multi plataforma en PHP?

Nota:

Esta pregunta será auto-respondida y la respuesta será marcada como Wiki de comunidad con el interés de que la misma sea editada con informaciones nuevas.

No estoy preguntando por manejar solamente los saltos de línea, sino que la intención de la pregunta es recopilar todos los posibles elementos que se puedan usar en PHP y que funcionen en todas las plataformas... no solamente los saltos de línea.

A. Cedano
  • 86,578
  • 19
  • 122
  • 221
  • 2
    primero que nada para que usas "\n" ... o bien "\r" – ArcanisGK507 Oct 24 '17 at 15:38
  • 1
    @FranciscoNúñez para imprimir, leer, escribir... saltos de línea, en pantalla o en un archivo u otro medio. Imaginemos que lo creas en Windows y luego quieres leerlo o compararlo en Mac OS. – A. Cedano Oct 24 '17 at 15:40
  • ok, entonces esto no tiene nada que ver con manejo de rutas, si no con la creacion de un archivo ejemplo un txt que pueda ser Visto en todos los Sistema Operativos. seria el caso de que lo creas en el servidor y ofreces su Descarga via web??? o tu deseas escribir de un servidor a otro servidor... ejemplo escrbir un txt de un servidor windows a uno mac o de uno linux a uno windows... – ArcanisGK507 Oct 24 '17 at 15:44
  • te recomendaría utilizar el salto de linea combinado `\r\n` pero no tengo un equipo mac os para saber si lo interpreta como debe de ser... en mi caso me ha solucionado problemas entre linux y Windows. – ArcanisGK507 Oct 24 '17 at 15:52
  • 2
    @FranciscoNúñez, Tan sencillo como usar `PHP_EOL` para conocer rápidamente qué tipo de salto de línea estás usando. – Muriano Oct 24 '17 at 16:48
  • eso no le va a funcionar @Muriano en el caso de que el quiera escribir en un servidor remoto el PHP_EOL utilizara el S.O Local para determinar el salto de linea eso no es funcional para este caso. – ArcanisGK507 Oct 24 '17 at 17:02
  • Pero @FranciscoNúñez parece que estás entendiendo la pregunta *al revés*... Si lees la respuesta Wiki más abajo esa es la solución para PHP 5.0+ **en el caso** del salto de línea. – A. Cedano Oct 24 '17 at 17:06
  • @A.Cedano PHP_EOL es de uso local, "para el sistema operativo actual" lo dice ... que pasa si vas a escribir a un servidor remoto por FTP un archivo tipo txt...y resulta que vas de windows a mac os??? – ArcanisGK507 Oct 24 '17 at 17:11
  • 1
    Posible duplicado de [¿Cómo crear espacios y saltos de línea en PHP con comillas simples?](https://es.stackoverflow.com/questions/97752/c%c3%b3mo-crear-espacios-y-saltos-de-l%c3%adnea-en-php-con-comillas-simples) – ArcanisGK507 Oct 24 '17 at 17:41
  • Si usas PHP no tiene mucho caso poner saltos de línea, pues la idea es generar HTML. La forma correcta casi siempre será poner un `
    ` y de esa manerra tendrías código multiplataforma. Si no te referías a eso, tal vez debas modificar la redacción de la pregunta.
    – Ruslan López Oct 24 '17 at 17:44
  • 1
    @RuslanLopezCarro PHP no se limita solamente a ser usado en HTML. Puedes por ejemplo usarlo para crear archivos de texto y en ese caso el uso de `
    ` no sería el adecuado. Además la pregunta no se limita solo a los saltos de línea. Puse ese ejemplo y cierta intervención constante aquí podría hacer pensar que se trata de manejar los saltos de línea solamente. Si lees la pregunta verás que ese no es el sentido de la misma.
    – A. Cedano Oct 24 '17 at 17:51
  • 1
    Vamos a ver @FranciscoNúñez **yo no estoy preguntando sobre como manejar los saltos de línea en PHP**, he mencionado los saltos de línea como un ejemplo ... creo que voy a tener que poner otro ejemplo porque el ejemplo te ha confundido. **Yo estoy preguntando** sobre cómo **escribir código multiplataforma en PHP**. – A. Cedano Oct 24 '17 at 17:54
  • mejora tu pregunta entonces, puede tener varias respuestas... ya que al decir multiplataforma abarca muchas cosas, desde hacer que tu repositorio de código corra en cualquier tipo de servidor, hasta que lo que salga de tu código (archivos, etc.) funcione, sea visible en cualquier sistema Operativo. – ArcanisGK507 Oct 24 '17 at 18:05

2 Answers2

6

Para lo casos que expones.

El salto de línea:

Usar PHP_EOL al manejar archivos.

El separador de rutas de archivos y El separador de directorios

Usar DIRECTORY_SEPARATOR

El directorio del usuario actual (home)

Es un indice del array $_SERVER pero este es un valor que enviá el cliente por lo que no podemos contar con el. bien podria no enviarlo el explorador. o el cliente.

Adicionalmente tener en cuenta lo siguiente:

El directorio temporal del sistema:

sys_get_temp_dir

No dar por echo parámetros por defecto en funciones.Por ejemplo la codificación que depende de la versión de PHP o el SO.

string htmlentities ( string $string [, int $flags = ENT_COMPAT | ENT_HTML401 [, string $encoding = ini_get("default_charset") [, bool $double_encode = true ]]]

Como esta hay muchas funciones que dependen de la codificación por defecto del SO versión de PHP o configuración de php.ini. Lo mas sano es usar funciones Multibyte, comprobar la codificación y forzarla a la de su elección.

Se pueden crear envolturas para las funciones de PHP por ejemplo y usar estas y en ellas hacer las validaciones de compatibilidad necesarias y retornar el valor que mas nos convenga.

function lower($str) {

    if (! function_exist('mb_strtolower')) {
       return strtolower($str);
    }
    return mb_strtolower($str,ENCODIG);
}

También podemos tratar de simular la funcionalidad de funciones en caso de que las extensiones no estén habilitadas:

if (! function_exists('mb_detect_encoding')) {


  function mb_detect_encoding ($string, $enc=null, $ret=null) {

      $enclist = array(
          'UTF-8', 'ASCII',
          'ISO-8859-1', 'ISO-8859-2', 'ISO-8859-3', 'ISO-8859-4', 'ISO-8859-5',
          'ISO-8859-6', 'ISO-8859-7', 'ISO-8859-8', 'ISO-8859-9', 'ISO-8859-10',
          'ISO-8859-13', 'ISO-8859-14', 'ISO-8859-15', 'ISO-8859-16',
          'Windows-1251', 'Windows-1252', 'Windows-1254',
          );

      $result = false;

      foreach ($enclist as $item) {
          $sample = iconv($item, $item, $string);
          if (md5($sample) == md5($string)) {
              if ($ret === NULL) { $result = $item; } else { $result = true; }
              break;
          }
      }

    return $result;
  } 
}

En las conexiones a base de datos hay que especificar el charset y no dejarlo a la negociación del cliente servidor.

Los nombres de los archivos y directorios siempre hay que validar como se han escrito en los include o referencias a los mismos ya que widow no es Case sensitive y los SO *nix si.

También hay que configurar nuestro editor para que al crear archivos los cree con una misma codificación y mismo final de linea preferentemente \r (*nix).

En el ambiente de desarrollo utilizar error_reporting y display_errors con los valores ALL y on respectivamente para así ser mas consientes de nuestras posibles fallas y minimizarlas lo mejor posible.

Evitar el uso de llamadas al sistema con shell_exec si fuese necesario configurar el path y documentarse respecto al programa que ejecutamos ya que su salida puede variar de acuerdo al SO especialmente en saltos de linea y codepage.

No hacer uso de los objetos COM ya que solo funcionan en window.

Por el momento son todas las consideraciones que recuerdo. si hay alguna que no entre en alguna categoría bienvenida en los comentarios.

Sergio Cauich
  • 1,527
  • 6
  • 8
4
  • Separadores de ruta y de línea

Cada sistema operativo tiene una forma diferente de representar los separadores de ruta y línea para los archivos. Las versiones de Unix y Mac OS modernas usan / como un separador de ruta y \n como un separador de línea, mientras que Windows usa \ o / como un separador de ruta y \r \n como un separador de línea. Para complicar aún más las cosas, algunas versiones antiguas de Mac OS utilizan \r como separador de líneas y : como separador de rutas, ¡las tres son diferentes!

Solución para separadores de rutas

Puede hacer que su vida sea más fácil usando barras diagonales (/) en todas partes, porque Windows acepta tanto \ como / como separadores de ruta. Si puede abstenerse de utilizar nombres de ruta específicos del sistema operativo como c:/home/website/index.php, entonces hágalo. Muy a menudo, solo /home/website/index.php funcionará perfectamente en todos lados.

Solución para separadores de líneas

Los separadores de líneas son un poco más complicados y, si no tiene PHP 5.0.2 o superior, la forma más fácil de manejarlos es poner unas líneas de código en su biblioteca de códigos compartidos que verifique el sistema operativo y almacene el carácter de línea final apropiado en una variable, puede reutilizar esa variable en todos los otros scripts. Si tenemos PHP 5.0.2 o superior, la constante PHP_EOL estará disponible para nosotros y representa el carácter de línea nueva apropiado para el sistema operativo actual.


Conocer la versión de PHP

Este script puede servir para ejecutar código según las versiones de PHP

$CurrentVer = phpversion()
print "Current PHP version: $CurrentVer\n";
     switch (version_compare($CurrentVer, '5.0.0') {
             case -1:
                     print "You're running an old PHP: $CurrentVer\n";
                     break;
             case 0:
                     print "You are running PHP 5\n";
                     break;
             case 1:
                     print "You are running a version of PHP after 5.0.0:
     $CurrentVer\n";
     }

Fuentes:

  • Paul Hudson, PHP in a nutshell.
A. Cedano
  • 86,578
  • 19
  • 122
  • 221
  • no tiene nada que ver con lo que solicita el wey... fijate los comentarios del post. – ArcanisGK507 Oct 24 '17 at 15:48
  • Al igual que pasa con los saltos de línea, que pueden ser sustituídos por la constante predefinida `PHP_EOL` (end of line), el separdor de directorios puede ser obtenido fácilmente usando `DIRECTORY_SEPARATOR` – Muriano Oct 24 '17 at 16:55
  • @Muriano excelente. Es Wiki de comunidad, la puedes editar si quieres. La idea era esa. – A. Cedano Oct 24 '17 at 16:57
  • Confieso que yo programo asumiendo que nadie usa windows. Y sé que es mentira pero si persisto en mi negación algún día será real – ffflabs Nov 10 '17 at 23:11