944 063 154

Blog

Habilitar subdominios wildcard con Plesk

Publicado enDominios

Los subdominios Wildcard son de gran utilidad para redirigir a tus visitantes a tu página principal; aunque hayan accedido a tu web por otra URL. De esta forma, puedes mejorar la estructura de tu sitio web o ayudar a tus usuarios a dar con tu web aunque hayan tecleado mal el dominio. Así, el uso de subdominios wildcard es casi imprescindible; ya que es habitual que cometamos errores otrográficos al buscar una página web. Igualmente si probamos a buscar una página web con www o sin ellas; llegaremos a la misma web. Además, algunas aplicaciones y CMS, como WordPress, crean de forma automática subdominios wildcard para proporcionar una mayor experiencia al usuario.

La manera más sencilla de crear subdominios wildcard es utilizando Plesk. El panel de control es de gran ayuda a la hora de gestionar un alojamiento web, de ahí que contar con uno en tu servidor cloud o hosting compartido sea casi obligatorio. Entre las diferentes tareas que Plesk simplifica se encuentra la creación de este tipo de subdominios para que todos apunten a una misma página; sin importar el subdominio que se haya utilizado para el acceso. Es decir, no importará que entren a tu web a través de www.tudominio.com o www.subdominio.tudominio.com. En cualquiera de los casos aterrizarán en tu página principal, o en cualquier otra que hayas definido previamente.

Para empezar a habilitar subdominios wildcard desde Plesk, solo tienes que acceder al panel de control.

Creando subdominios wildcard desde Plesk

Una vez dentro de tu panel de control Plesk, en primer lugar, tendremos que añadir un registro en la zona DNS. Por supuesto, deberemos asegurarnos de que el directorio raíz del subdominio se corresponde con el dominio principal. Es decir, algo similar a lo siguiente, ya que de otra manera no será posible redirigir a tus visitas a tu web principal:


*.dominio.com.; CNAME; dominio.com

A continuación, dentro del directorio /conf debemos crear, o editar dependiendo del caso, el archivo vhost.conf. La nueva sintaxis del archivo deberá estar de la siguiente manera:


ServerAlias *.dominio.com

Por último, tendremos que ejecutar el siguiente comando en bash. De esta forma nos aseguramos de que se apliquen de forma correcta todos los cambios que hemos introducido.


/usr/local/psa/admin/bin/websrvmng -av

A partir de ahora se acabaron las preocupaciones sobre dónde aterrizarán tus visitas; todas ellas llegarán a la URL que tú hayas decidido gracias a la creación de subdominios wildcard. Esta es solo una de las múltiples funcionalidades del panel de control Plesk, un servicio que si aún no has contratado, deberías hacerlo cuanto antes. Con Plesk, gestionar un alojamiento web nunca fue más fácil.

Un vistazo a Doctrine 2

Publicado enDesarrollo y Programación

Doctrine es un ORM que cada vez estamos usando más y más aquellos que trabajamos con el framework Symfony para PHP. En los últimos días se ha publicado Doctrine 2, la nueva versión del modelo de programación. Una actualización del ORM que, entre otras cosas, permite transformar las tablas de las bases de datos.

Esta nueva versión de Doctrine está reescrita por completo en PHP 5.3. Esto permite mejorar su rendimiento de una forma notable y haciendo que su uso sea mucho más ágil.

Jonathan Wage, impartió en Febrero de este año durante la conferencia Symfony Live 2010 una interesante charla en la que dió a conocer algunas de las novedades más interesantes que se recogen en esta nueva versión.

Las principales novedades de Doctrine 2

Doctrine 2 da la vuelta a su código, a los conceptos y también incorpora un nuevo flujo de trabajo. Aunque tanto cambio pueda asustar en un principio, en esta ocasión solo trae cosas buenas. Y es que todos los cambios provienen de lo aprendido de Doctrine 1, por lo que la mejora del ORM es más que notable.

Por ejemplo, con Doctrine 2 se duplican los datos de su anterior versión y las consultas se ejecutan en un tiempo mucho menor. Además, se incluye OOP,  nuevas queries e implementaciones que ayudan a agilizar el cacheo de los resultados.

Para su desarrollo se ha utilizado PHP Unit 3.4.10, componentes Symfony YAML, Sismo o Subversion. Aunque todas estas incorporaciones han provocado cambios en la arquitectura, ahora será mucho más sencillo. Esto se debe a que, entre otras cosas, ya no habrá imposiciones del modelo de dominio.

Asimismo, es posible utilizar los sistemas de gestión de bases de datos (DBMS) a través de Sqlite, MySQL, Oracle o PgSQL. En la misma línea, la capa de abstracción de la base de datos ha mejorado considerablmente respecto a Doctrine 1; tanto en relación a la API como a su estructura, incorporándose además en PHP 5.3.

Aspectos a tener en cuenta

Otros elementos a considerar en relación a Doctrine 2 son:

  • El modelo de dominio no viene impuesto por Doctrine, sino que está definido en PHP. Esto supone una mejora notable.
  • Mayor facilidad para entender lo que está pasando en la aplicación, en vez de dejar que la ‘magia’ de Doctrine 1 ocurra.
  • Las entidades no requieren de la extensión de la clase base.
  • Aunque realices múltiples transacciones se ejecutarán como si fuse una. Así, los tiempos respecto a PHP se reducen, ya que aquí las transacciones se efectúan individualmente.

Si quieres saber más acerca de Doctrine 2, Jonathan Wage ha publicado un documento con los cambios más significativos de la nueva versión e Doctrine.

Importar una base de datos a SQL Azure (II de II)

Publicado enSistemas TI

En un artículo anterior veíamos cómo podíamos importar una base de datos a SQL Azure utilizando un Wizard para ello. En esta ocasión vamos a realizar la operación directamente a través de SQL Server Management Studio (SSMS). Para ello, tendremos que generar un script.

Antes de nada, deberemos comprobar si tenemos compatibilidad con Azure. Para ello, es necesario tener instalada la versión R2 de SQL Server Management Studio. Si no cuentas con la última actualización de esta aplicación, te recomendamos que antes de realizar nada, actualices a R2. Puedes descargar la última versión de SQL Management Studio en su sitio oficial. Algo que también explicábamos en el artículo anterior sobre la importación de una base de datos SQL Azure.

De local a un script

Para poder exportar la base de datos en local y llevarla a un script en un formato que sea compatible con Azure. Pero antes debemos conectarnos desde SSMS a nuestro server local. Una vez realizada la conexión, podremos realizar la exportación de la base de datos en el formato de Azure. Para ello, utilizaremos el asistente de la aplicación que permite la generación de scripts.

En primer lugar, y una vez dentro de Microsoft SQL Server Management Studio, debemos buscar la base de datos «eventos». Recuerda que tú tendrás que elegir el nombre de tu base de datos, «eventos» es el que le hemos dado a nuestra base de datos de ejemplo. A continuación, haciendo click con el botón derecho del ratón, elegiremos tareas > generar scripts de entre las opciones que se despliegan en el menú.

importar una base de datos a sql azure-export

importar una base de datos a sql azure-script

En nuestro caso, vamos a exportar todas las tablas y los usuarios que se encuentran dentro de la base de datos. Si en tu caso solo necesitas exportar unos datos en concreto, este es momento de que lo indiques. De esperar a hacerlo más adelante, ya no será posible y tendrás que descargar todo el contenido de la base de datos.

importar una base de datos a sql azure-objetos

En este paso debemos indicar dónde queremos que se guarde el script que estamos a punto de generar. Para ello, tenemos que acceder a las opciones Avanzadas para especificar qué queremos exportar en el formato para Azure. Así, podremos hacerle saber que queremos incluir tanto el esquema como todos los datos que se recogen en la base de datos.

importar una base de datos a sql azure-scripting

importar una base de datos a sql azure-opciones

Con esto, nuestro script ya está listo. Ahora, es el momento de iniciar la importación de la base de datos que hemos exportado previamente en nuestro servidor SQL Azure.

importar una base de datos a sql azure-resumen

importar una base de datos a sql azure-guardar script

Importar una base de datos a SQL Azure

Una vez hemos descargado la base de datos, deberemos seguir los siguientes pasos para subirla a SQL Azure. Para ello, en primer lugar, debemos conectar nuestro servidor con el servicio SQL Azure. Conectar con el servidor es algo tan simple como iniciar iniciemos sesión.

SQL Server 2008 R2-importar una base de datos a sql azure

Una vez dentro de nuestra suscripción, y al igual que cuando hemos realizado la importación a través de Wizard, necesitamos crear una nueva base de datos. Como en el anterior tutorial, hemos llamado a esta nueva base de datos «eventos». En tu caso puedes ponerle el  nombre que prefieras.

Crear base de datos-importar una base de datos a sql azure

Por último abrimos nuestro script y lo ejecutaremos en el servidor SQL Azure cuando aparezca el mensaje de que los comandos han sido completados de forma correcta.

importar una base de datos a sql azure

De esta forma, nuestra base de datos local en SQL Server, ya estará importada en Azure.

importar una base de datos a sql azure-explorador

Aquí termina nuestro tutorial paso a paso de cómo importar una base de datos a SQL Azure. Y ya sabes, no dudes en escribir si tienes alguna duda o consulta; estaremos encantados de atenderte.

ASP.NET con IIS 7.5 y Plesk 9.3

Publicado enGeneral

Ya está disponible la nueva actualización de Plesk; y con ello hemos detectado el siguiente problema tras instalar Plesk 9.3 sobre Windows Server 2008 R2: «ASP.NET no está autorizado para acceder al recurso solicitado» (is not authorized to access the requested resource).


 Server Error in '/mssql' Application.
 --------------------------------------------------------------------------------

 Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))
 Description: An unhandled exception occurred during the execution of
 the current web request. Please review the stack trace for more
 information about the error and where it originated in the code.

 Exception Details: System.UnauthorizedAccessException: Access is
 denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))

 ASP.NET is not authorized to access the requested resource. Consider
 granting access rights to the resource to the ASP.NET request
 identity. ASP.NET has a base process identity (typically
 {MACHINE}ASPNET on IIS 5 or Network Service on IIS 6) that is used if
 the application is not impersonating. If the application is
 impersonating via , the identity will be
 the anonymous user (typically IUSR_MACHINENAME) or the authenticated
 request user.

 To grant ASP.NET access to a file, right-click the file in Explorer,
 choose "Properties" and select the Security tab. Click "Add" to add
 the appropriate user or group. Highlight the ASP.NET account, and
 check the boxes for the desired access.

 Source Error:

 An unhandled exception was generated during the execution of the
 current web request. Information regarding the origin and location of
 the exception can be identified using the exception stack trace below.

 Stack Trace:

 [UnauthorizedAccessException: Access is denied. (Exception from
 HRESULT: 0x80070005 (E_ACCESSDENIED))]

 [FileLoadException: Could not load file or assembly
 'System.ServiceModel, Version=3.0.0.0, Culture=neutral,
 PublicKeyToken=b77a5c561934e089' or one of its dependencies. Access is
 denied.]
 System.Reflection.Assembly._nLoad(AssemblyName fileName, String
 codeBase, Evidence assemblySecurity, Assembly locationHint,
 StackCrawlMark&; stackMark, Boolean throwOnFileNotFound, Boolean
 forIntrospection) +0
 System.Reflection.Assembly.nLoad(AssemblyName fileName, String
 codeBase, Evidence assemblySecurity, Assembly locationHint,
 StackCrawlMark&; stackMark, Boolean throwOnFileNotFound, Boolean
 forIntrospection) +43
 System.Reflection.Assembly.InternalLoad(AssemblyName assemblyRef,
 Evidence assemblySecurity, StackCrawlMark&; stackMark, Boolean
 forIntrospection) +127
 System.Reflection.Assembly.InternalLoad(String assemblyString,
 Evidence assemblySecurity, StackCrawlMark&; stackMark, Boolean
 forIntrospection) +142
 System.Reflection.Assembly.Load(String assemblyString) +28

 System.Web.Configuration.CompilationSection.LoadAssemblyHelper(String
 assemblyName, Boolean starDirective) +46

 [ConfigurationErrorsException: Could not load file or assembly
 'System.ServiceModel, Version=3.0.0.0, Culture=neutral,
 PublicKeyToken=b77a5c561934e089' or one of its dependencies. Access is
 denied.]

 System.Web.Configuration.CompilationSection.LoadAssemblyHelper(String
 assemblyName, Boolean starDirective) +613

 System.Web.Configuration.CompilationSection.LoadAssembly(AssemblyInfo
 ai) +57

 System.Web.Compilation.BuildManager.GetReferencedAssemblies(CompilationSection
 compConfig) +178
 System.Web.Compilation.BuildProvidersCompiler..ctor(VirtualPath
 configPath, Boolean supportLocalization, String outputAssemblyName) +54

 System.Web.Compilation.ApplicationBuildProvider.GetGlobalAsaxBuildResult(Boolean  isPrecompiledApp)
 +232
 System.Web.Compilation.BuildManager.CompileGlobalAsax() +51
 System.Web.Compilation.BuildManager.EnsureTopLevelFilesCompiled()  +337

 [HttpException (0x80004005): Could not load file or assembly
 'System.ServiceModel, Version=3.0.0.0, Culture=neutral,
 PublicKeyToken=b77a5c561934e089' or one of its dependencies. Access is
 denied.]

 System.Web.Compilation.BuildManager.ReportTopLevelCompilationException()
 +58
 System.Web.Compilation.BuildManager.EnsureTopLevelFilesCompiled()  +512

 System.Web.Hosting.HostingEnvironment.Initialize(ApplicationManager
 appManager, IApplicationHost appHost, IConfigMapPathFactory
 configMapPathFactory, HostingEnvironmentParameters hostingParameters)
 +729

 [HttpException (0x80004005): Could not load file or assembly
 'System.ServiceModel, Version=3.0.0.0, Culture=neutral,
 PublicKeyToken=b77a5c561934e089' or one of its dependencies. Access is
 denied.]
 System.Web.HttpRuntime.FirstRequestInit(HttpContext context)  +8897659
 System.Web.HttpRuntime.EnsureFirstRequestInit(HttpContext context)  +85

 System.Web.HttpRuntime.ProcessRequestNotificationPrivate(IIS7WorkerRequest  wr,
 HttpContext context) +333

¿Cómo corregimos el error de ASP.NET?

El error se podía reproducir al tratar de ejecutar una aplicación desde Plesk. En nuestro caso al lanzar el administrador web para bases de datos SQL Server ASP.NET Enterprise Manager o MyLittleAdmin que se ejecutan desde Plesk.

Si tratamos de corregir el error desde la herramienta Plesk Reconfigurator no solucionaremos el problema debido a que los permisos necesarios no están añadidos. Por ello, tendremos que hacerlo a mano.

Lo único que tenemos que hacer es editar el archivo DiskSecurity.xml que encontraremos en la carpeta %PLESK_DIR%etcDiskSecurity y añadirle el siguiente contenido dentro del tag Entries:


<!-- Permisos a Assembly para ASP.NET Enterprise manager -->

<Entry AccounType="1" Account="Psacln" Path="C:Windowsassembly" AceFlags="FilesOnly" AccessMask="Read" EntryFlags="0x0" /&>

Finalmente hay que ejecutar el siguiente comando en bash para que se apliquen los cambios en los permisos:


"%plesk_bin%applysecurity" --apply

 

Recuerda que también ofrecemos servicios para ASP.net MVC y PHP bajo Windows.

Aunque pueda parecer contradictorio debido a los errores que hemos tenido que subsanar, desde Linube te aconsejamos tener siempre SQL Server actualizado.

Importar una base de datos a SQL Azure (I de II)

Publicado enServidores cloud

En el siguiente post veremos cómo subir una base de datos local en SQL Server 2008 al servicio SQL Azure. Para ello, cuentas con varias maneras de importar una base de datos a SQL Azure:

  1. Mediante los servicios de integración de SQL Server 2008 (SSIS).
  2. Utilizando BCP para copiar los datos desde una base de datos a la otra.
  3. Desde el código, usando la clase System.Data.SqlClient.SqlBulkCopy.
  4. Utilizando wizards o scripts para la carga de los datos.

En este artículo, utilizaremos la ultima opción para mostrar qué tendrás que hacer para importar la base de datos.

El cloud de Microsoft

Antes de comenzar con la importación de la base de datos, recordemos que Azure, la nube de Microsoft, tiene algunas limitaciones. Por ejemplo, Azure no permite la importación de bases de datos mediante un «restore», ni tampoco ofrece la posibilidad de adjuntar una base de datos al servidor SQL de Azure. Además, ten en cuenta de que para poder realizar la importación de una base de datos, en primer lugar, es necesario crear un servidor SQL Azure. A continuación, habrá que copiar el nombre del servidor que hemos creado, ya que es necesario conocerlo para saber dónde tenemos que conectarnos.

En nuestro caso, hemos aprovechado este paso para crear una nueva base de datos a la que hemos llamado «eventos». Esto es un paso opcional, ya que como veremos más adelante es posible crear nuevas bases de datos desde el propio Wizard. Wizard es el asistente que permite la creación de hasta 149 bases de datos por servidor SQL Azure y con un tamaño máximo de 1 GB ó 10 GB.

Importando una base de datos con SQL Azure

En primer lugar, deberemos acudir a nuestra suscripción de Windows Azure Services. Una vez hayamos iniciado sesión, deberemos pinchar en SQL Azure > Database. Allí podremos ver cuántas bases de datos tenemos alojadas en el servidor, cuál es el tipo de cada una de ellas y qué tamaño ocupan tanto de forma individual como colectiva.

 

SQL Azure

 

Al lado de la pestaña Databases, se encuentra la de Firewall Settings. Aquí tenemos que añadir al menos una regla que permita la conexión desde nuestro equipo al servidor. En nuestro caso contamos con 3 reglas diferentes para la funcionalidad de Firewall.

Firewall

Ahora utilizaremos SQL Azure Migration Wizard para poder migrar de una forma más sencilla la base de datos. La descarga de esta aplicación está disponible en el sitio oficial de CodePlesk. Para instalarla, sólo hay que seguir el asistente de instalación que integra la propia aplicación. Un proceso tan sencillo que no es necesaria la explicación, por lo que pasaremos este paso muy por encima. Pero por si acaso te surje alguna duda, adjuntamos los pantallazos del proceso a modo de resumen.

SQL Migration Wizard 1

SQL Azure Migration Manager 2

SQL Azure Migration Manager 3

SQL Azure Migration Manager 4

SQL Azure Migration Manager 5

SQL Azure Migration Manager 6

SQL Azure Migration Manager 7

SQL Azure Migration Manager 8

SQL Azure Migration Manager 9

Si tienes instalado Microsoft SQL Server Management Studio R2, ya puedes conectarte a tu servidor SQL Azure. Y, si no cuentas con esta herramienta, te facilitamos un enlace para que puedas iniciar la descarga. Como en el caso anterior, la instalación es muy sencilla y solo tendrás que seguir los pasos del asistente de Microsoft Management Studio.

sql2008R2

Una vez instalado, en Microsoft SQL Server Management Studio, solo tienes que acudir al explorador de objetos y proceder a conectar el servidor. Una vez estés conectado al servidor, deberás abrir la carpeta que lleva el mismo nombre del servidor al que quieres acceder. Y dentro de esta, tendrás que buscar la carpeta que has creado con anterioridad. Recordamos que a dicha carpeta nosotros le hemos dado el nombre de «eventos»; tú tendrás que buscar la que se corresponda con el nombre que le habías asignado.

SQL 2008 Management Studio R2

¿Buscas otra forma diferente de realizar la importación de una base de datos a SQL Azure? Consulta la segunda parte de cómo importar una base de datos a SQL Azure.

Trabajando con Windows Azure y PHP primer deploy

Publicado enSistemas TI

Una de las primeras dudas que nos entran a la hora de pensar en Azure, es si Windows Azure es algún tipo de instancia virtual a la que podemos acceder vía escritorio remoto y configurar lo que necesitemos en nuestro servidor. Sentimos decirte… que no.

Azure es un concepto distinto a esto; un planteamiento o paradigma nuevo a la hora de pensar en el alojamiento de nuestras aplicaciones web en internet. Exige en un principio estar abiertos a un cambio, un cambio necesario que se impondrá sin ninguna duda durante los próximos años.

Azure es un entorno formado por varios roles a los que subiremos según el tipo de rol de nuestra instancia, nuestra aplicación, nuestra base de datos, nuestros archivos estáticos y nuestros procesos backend. Todo está pensado para ser modular y escalable sin provocar dolores de cabeza al desarrollador. Estos roles se comunicarán entre sí mediante Rest vía HTTP o sockets TCP/IP. El coste será por horas de servicio y, aunque las instancias estén paradas se seguirán cobrando.

En Windows Azure principalmente tenemos los siguientes roles:

  • Web Role: Destinado a servir aplicaciones web frontales, escritas en .NET, PHP, Ruby, Perl, Python o cualquier lenguaje que soporte FastCGI.
  • Worker Role: Destinado a servicios que funcionen en el backend, los primeros que se nos vienen a la mente pueden ser mysql o memcached.

Adicionalmente tenemos estos otros servicios en Windows Azure:

  • SqlAzure: Una versión de SQL Server 2008 implementada en Azure.
  • Storage: Un repositorio de archivos con el que podremos trabajar desde nuestras aplicaciones web.

En este primer acercamiento me voy a centrar en el WebRole y por la naturaleza de nuestra aplicación web, será de tipo FastCGI para poder ejecutar aplicaciones PHP.

Para programar en php bajo entorno Microsoft uso Visual Studio 2008 + vs.php o netbeans (en este caso usaré lo primero). Si no usas visual studio, dispones de herramientas que te permiten trabajar de una forma similar pero utilizando Eclipse. Recuerda que si estás en la universidad o has terminado hace poco, existen descargas gratuitas completas de Visual Studio y horas de servicio Azure en dreamspark.

Lo primero es crear un servicio tipo Windows Azure en el panel de control de la plataforma azure.

windows azure-platform

Una vez creado el servicio vemos que disponemos de dos entornos, uno de integración y otro de producción. Nos cobrarán por tener instancias en ambos entornos, estén levantadas o no.

windows azure-frontal

Para poder trabajar con Azure desde visual studio, nos tenemos que descargar el SP1 y las Windows Azure Tools for Microsoft Visual Studio que nos permitirán disponer de un entorno basado en IIS similar a azure.

Una vez hecho esto, en Visual Studio podremos seleccionar un tipo de proyecto Windows Azure Cloud Service.

Tras seleccionar el tipo de proyecto, nos preguntará qué rol vamos a asignar a este proyecto. En nuestro caso al ser una aplicación php, le asignamos el rol WebCGI role.

windows azure-visual studio

windows azure-proyecto

Una vez completado este paso, se nos crearán dos proyectos en el árbol de soluciones de Visual Studio y se nos mostrará el contenido del archivos de configuración del WebRole: el Web.roleconfig. Este es un archivo xml tipo al Web.config y en el que aparece entre las llaves FastCGI el siguiente comentario:


&lt;-- Set the "Enable Full Trust" property to true on the corresponding
 Web Role in the Cloud Service project.
 --&gt;

&lt;-- Define the fastCgi application here. The application must be located
 under the role root folder or subfolder. The handler is defined in
 the Web.config file.

 Ensure that all of the handler binaries have their "Build Action" Solution
 Explorer file property set to "Content".

&lt;application fullPath="%RoleRoot%approotcgi-handler.exe" arguments="arg1 arg2 ..." /&gt;
 --&gt;

Nos pide que realicemos las siguientes tareas:

  • Que subamos la aplicación fastCGI encargada de procesar las peticiones a nuestra aplicación. Los binarios de la aplicación deben estar en el directorio raíz de nuestro proyecto (representado por la constante %RoleRoot%approot) y debemos configurar el handler en el web.config de la aplicación.
  • Tenemos que activar la propiedad «Full Trust» en la configuración del WebRole.

Vamos a ello:

1) Primero nos descargamos los binarios o instalamos el msi (te recomiendo lo segundo) la última versión de PHP en windows.php.net

2) Una vez descargado o instalado php, copiamos sus binarios tal cual al directorio raíz de nuestro proyecto (a un directorio llamado /php). Si has instalado PHP, normalmente te dejará los binarios en «c:archivos de programaphp».

3) Si ya tenemos el directorio PHP en nuestra raíz del proyecto, indicaremos donde se encontrará la aplicación en el Web.roleconfig


&lt;?xml version="1.0"?&gt;
&lt;configuration&gt;
 &lt;system.webServer&gt;
 &lt;fastCgi&amp;gt;
    &lt;application fullPath="%RoleRoot%approotphpphp-cgi.exe" arguments="" /&gt;
  &lt;/fastCgi&gt;
&lt;/system.webServerp&gt;
&lt;/configuration&gt;

4) En el web.config descomentamos las líneas dedicadas al Handler FastCGI y las dejamos como siguen:

&lt;add name="FastGGI Handler"
 verb="*"
 path="*.php"
 scriptProcessor="%RoleRoot%approotphpphp-cgi.exe"
 modules="FastCgiModule"
 resourceType="Unspecified" /&gt;

5) En las propiedades del Rol WebCgi nos aseguramos que está activada la propiedad Full Trust de .net

windows azure-full trust

6) Subimos nuestra aplicación php. En este caso, subiré una sencilla aplicación que hará una tirada basándose en el bastante poco óptimo sistema aleatorio de PHP para otorgarme puntos en diferentes niveles de ataque y defensa.

Después de hacerlo, escribirá el resultado en un archivo de texto pero estará disponible tan sólo de forma temporal. Si quisiéramos almacenarlo de forma persistente, deberíamos almacenarlo en Azure Storage.

El código es el siguiente:


<php
$poderes = array(
 "resistencia al fuego",
 "resistencia al frio",
 "aguante",
 "formulas de excel",
 "mirada penetrante",
 "escalabilidad",
 "ROI",
 "SEO",
 "SEM",
 "SMO",
 "pensamiento deslumbrante");

$resultado = null;

for($i=1;$i<;10;$i++){

 $puntos     = $i*1E2*rand(5,11);
 $poder      = $poderes[rand(0,10)];
 $resultado .= $puntos . " puntos en " . $poder;
 $resultado .= "n";

 echo "Asier ha obtenido " . $puntos . " puntos en " . $poder . "&<br/>";

}

$fp = fopen("resultados.txt","w+");
fwrite($fp, $resultado, strlen($resultado));
fclose($fp);

7) Si estamos ejecutando Visual Studio como Administrador podemos compilar el proyecto. Sino, lo cerramos y ejecutamos Visual Studio con privilegios de Administrador. Una vez compilada la aplicación se nos abrirá nuestro navegador ejecutando nuestra aplicación php.
Por defecto, si no le indicamos un archivo raíz, nos dará un error que nos detalla que no tenemos permiso para listar el directorio raíz.
Para que nos cargue un archivo inicial, podemos agregarle la clave defaultDocument a la configuración system.webServer en el web.config.

<system.webServer>
<defaultDocument enabled="true">
 <files>
    <add value="index.php"/>
   </files>
 </defaultDocument>

8) Vale en principio tenemos todo funcionando en local, ya que vemos que se ejecuta la aplicación y que escribe las puntuaciones en el archivo de texto.
Ahora necesitamos subir todo esto a Azure.

Si volvemos al panel de control de windows.azure.com, y pulsamos en el botón deploy en el entorno de integración vemos que se nos pide subir dos archivos; El paquete de la aplicación y el archivo de configuraciones.

windows azure-panel de control

Desde Visual Studio podemos generar muy fácilmente estos dos archivos al hacer click en la opción Publicar, que aparece al hacer click en el botón derecho sobre el proyecto de Azure.

Cuando lo hagamos, se nos abrirá la ventana en el navegador del Panel de control de Azure y una ventana en el explorador de windows con la ruta donde se han generado los archivos.

Una vez subidos le damos a Run, e iniciará la instancia. Tarda varios minutos.

Tras la espera podemos ejecutar nuestra aplicación desde la ruta que nos indique el panel de control.

windows azure-ruta

Hay otras herramientas de las que podemos beneficiarnos al crear aplicaciones en Azure, una de ellas es el gran módulo de rewrite de IIS7 con el que podemos utilizar urls amigables en nuestras aplicaciones web.

Vamos a hacer que nuestra aplicación otorgue le de poderes a un usuario que le indiquemos por URL.

Para ello tenemos que añadir una regla de rewrite en el web.config, dentro de system.webserver, en la que le indiquemos por la ruta /user/[nick] se le pasará como parámetro GET al script index.php.


<rewrite>
 <rules>;
    <rule name="Rewrite">
       <match url="^user/([a-z]+)" />
    <action type="Rewrite" url="index.php?user={R:1}" />
    </rules>
 </rules>
</rewrite>

En la aplicación recuperamos el parámetro GET. Tendríamos el siguiente código en el index.php


<php
$poderes = array(
  "resistencia al fuego",
  "resistencia al frio",
  "aguante",
  "formulas de excel",
  "mirada penetrante",
  "escalabilidad",
  "ROI",
  "SEO",
  "SEM",
  "SMO",
"pensamiento deslumbrante");

$resultado = null;

$usuario = "asier";
if(!empty($_GET) ; is_array($_GET) ; key_exist("user", $_GET)){
  $usuario = ucfirst($_GET["user"]);
}

for($i=1;$i < 10;$i++){

  $puntos     = $i*1E2*rand(5,11);
  $poder      = $poderes[rand(0,10)];
  $resultado .= $puntos . " puntos en " . $poder;
  $resultado .= "n";

  echo $usuario . " ha obtenido " . $puntos . " puntos en " . $poder . "<br/>

}

$fp = fopen("resultados.txt","w+");
fwrite($fp, $resultado, strlen($resultado));
fclose($fp);

Una función que me resulta imprescindible también es poder visualizar los logs de nuestra instancia. Esto podemos hacerlo desde el panel de control de Azure y una cuenta de storage.

Con esto hemos visto como ejecutar aplicaciones web sencillas php en Azure, en las próximas entregas veremos como usar los Worker Roles, SQL Azure y cómo trabajar con php azure para almacenar y recuperar archivos en Azure Storage.

Cosas que echamos en falta en Windows Azure

Entre las cosas que he echado en falta, y desconozco por ahora si Azure las permite de forma nativa o con herramientas de terceros, pueden ser las siguientes:

  • Un módo más ágil para hacer deploy de nuestras aplicaciones. Los desarrolladores web php estamos acostumbrados a usar subversion o rsync para hacer deploy de nuestras aplicaciones. El hecho de tener que generar un paquete y luego subirlo, es un paso que estaría genial si se automatizase. Lo más lógico podría ser que desde la opción «publicar» de visual studio se subiesen los cambios al entorno de integración de azure. O al menos, a Azure Storage; para que luego se haga el deploy definitivo con un botón desde el panel de control web de azure.
  • Posibilidad de personalizar el directorio público a la que se tendrá acceso desde el servidor web. En algunos frameworks como Symfony, el directorio público no es el directorio raíz de la aplicación por seguridad.
  • Algún modo para gestionar los permisos de los directorios de la aplicación. No es para nada seguro tener permisos de escritura en todos los directorios de nuestra aplicación.
  • Posibilidad de ejecutar scripts php o powershell vía cmd en la instancia. Imaginemos que necesitamos vaciar un directorio en el que almacenamos archivos de caché o archivos temporales, podemos hacerlo mediante algún script que se ejecute vía web, pero igual puede interesarnos realizar estas gestiones o alguna otra mediante línea de comandos.

El driver php_sqlsrv para SQL Server 2005 o superior en PHP

Publicado enDesarrollo y Programación

Desde hace algunos años el driver que se facilita en los paquetes de PHP por defecto está considerado deprecated y no se aconseja su uso. Sobre todo desde que fue publicada la última versión: SQL Server 2005. En su lugar, por suerte, disponemos del driver php_sqlsrv. Una extensión creada desde Microsoft con la que podemos aprovechar de una forma mucho más avanzada este expléndido motor de bases de datos.

Traducción nativa de los datos a utf-8

Una de las características que más me han gustado en la versión 1.1 del driver php_sqlsrv, es la traducción nativa y transparente de la codificación de los datos desde UTF-8 a UCS-2 y viceversa. Para quien haya tenido un mínimo de experiencia desarrollando aplicaciones en internet, la importancia de usar codificación UTF-8 es clave. Nos puede evitar pasar varias noches sin dormir al encontrarnos multitud de problemas al integrar aplicaciones, consumir datos de fuentes externas o migrar a otras plataformas. Es un detalle que los desarrolladores de esta librería le hayan dado prioridad a esta característica vital para desarrolladores de aplicaciones PHP.

Para activar esta característica, que os recomiendo que lo hagáis, basta con especificar el enconding en el array de conexión:

$params = array(

"UID" => "usuario",
"PWD"  =>"password",
"Database" => "base_de_datos"

);

$params["CharacterSet"] = "utf-8";
$conexion = sqlsrv_connect( "nombre_de_la_instancia", $params);

Campos de tipo fecha recuperables como cadenas

Por defecto el driver nos permite recuperar los datos de tipo datetime, Date, Time, DateTime2 y DateTimeOffset como datos DateTime. Normalmente nos puede interesar más tratarlos como si fuesen cadenas desde PHP y para ellos, el driver nos provee de una forma de hacerlo.

Basta con inidicarlo en el array de conexión:

$params = array(

"UID"=> "usuario",
"PWD" = > "password",
"Database" => "base_de_datos",
"CharacterSet" => "utf-8"

);

$params["ReturnDatesAsStrings"] = true;

$conexion = sqlsrv_connect( "nombre_de_la_instancia", $params);

Autenticación de sistema o de usuario de SQL Server 2005

A la hora de conectarnos a una instancia, podemos hacerlo mediante autenticación de sistema o de usuario de SQL Server según esté establecido en la configuración de la instancia.

Aunque para una aplicación web, especialmente una aplicación que tenga como destino dar servicio en internet, nos interese aplicar una autenticación de usuario de SQL Server, el driver dispone de soporte nativo para reconocer el usuario con el cual estamos ejecutando la aplicación web y usar sus credenciales para realizar la autenticación.

Para realizar una autenticación de sistema no necesitamos indicar usuario ni contraseña, tan sólo la base de datos:

$params =  array("Database" => "base_de_datos");

$conexion = = sqlsrv_connect( "nombre_de_la_instancia", $params);

Limpieza de parámetros en las consultas

Uno de los puntos más vulnerables en una aplicación web siempre ha sido la forma en la que realizamos las consultas a la base de datos.

Para ayudarnos a securizar los datos que interoducimos en las consultas, disponemos de un mecanismo muy sencillo de limpieza.

$sql = "INSERT INTO usuarios (email, password) VALUES (?,?);";

//creamos el array de parámetros
$params = array(strtolower($email),md5($pass));

//realizamos la consulta, pasándole los parámetros a blindar
$stmt = sqlsrv_query( $conexion, $sql, $params);

Instanciación de objectos específicos en los resultados de una consulta

Otra opción muy útil que nos provee el driver es la posibilidad de especificar un objeto que será instanciado como resultado de una query.

class User{
 public $object_id= null;
 public $user_id = null;
 public $email = null;
 public $password = null;

 public function __construct($id){
   $this->object_id = $id;
 }

}

$sql = "SELECT TOP 1 user_id,email FROM users WHERE user_id = ? ";

$stmt = sqlsrv_query( $conexion, $sql, array($user_id));

if($stmt!==false){

 $i=0; $items = array();

 //cada variable $object será una instancia del objeto User
 while( $object = sqlsrv_fetch_object( $stmt, "User", array($i)))
 {
  $items[] = $object;
  $i++;
 }

 sqlsrv_free_stmt($stmt);
 $stmt=null;
}

Constantes para la conversión de tipos PHP a tipos nativos de SQL Server

En algunos casos necesitamos convertir el parámetro al tipo de dato nativo de SQL Server que necesitemos evaluar en la consulta. Como puede ser el caso de los tipos DateTime.

Para ello, el driver php_sqlsrv dispone de una serie de constantes que nos ayudan a hacerlo.

$sql = "SELECT user_id FROM usuarios WHERE created_at >= ? AND user_id < ?;";

//creamos el array de parámetros, cada elemento será un array en el que especifiquemos la constante del tipo que necesitamos
$params = array(array($date, null, null, SQLSRV_SQLTYPE_DATETIME), array($user_id,null));

//realizamos la consulta, pasándole los parámetros a blindar
$stmt = sqlsrv_query( $conexion, $sql, $params);

Opciones que echamos en falta en el driver php_sqlsrv

PDO es una capa de abstracción cuyo objetivo principal es aislarnos de las particularidades de cada driver disponible. Todo ello con el objetivo de atacar los diferentes motores de bases de datos que existen. Muchos ORMs como doctrine y Propel lo usan. No disponer de soporte para PDO supone una barrera para algunso de los CMS o frameworks más usados. Además de un trabajo adicional para los desarrolladores a la hora de necesitar utilizar SQL Server en sus proyectos. Irónicamente, el antiguo driver a pesar de estar obsoleto soporta PDO.

Se agradece ir abandonando poco a poco el paradigma estructurado en PHP y algunas librerías como MySQLi; que nos permiten usarlas como si se tratase de un objeto. Sería una muy buena característica para este driver.

Si quieres saver más sobre PHP, en concreto cómo crear consultas del tipo select count en PHP, podrás encontrarlo también en nuestro blog.

Soluciones en WordPress a problemas de MySQL y cache

Publicado enDesarrollo y Programación

Hace algunos días se formó un interesante debate en torno a un post en Loogic. En él se hablaba de la problemática de tener cuello de botella en el backend de base de datos de una aplicación web. Desde nuestra experiencia podemos decir que no es tanto culpa de la base de datos, sino de la programación en la aplicación. También puede ser consecuencia de una mala o desatendida gestión en la base de datos y configuración del servidor.

Se suele decir que un CMS tiene una mala gestión de consultas sobre la base de datos, que abusa de ellas o que hace chapuzas. Algo que, a veces, puede ser cierto. Pero esas afirmaciones también peuden radicar en un desconocimiento técnico sobre cómo funciona realmente la herramienta y qué cuidados requiere.

La base de datos de WordPress

Podemos ahorrarnos muchas consultas a la base de datos desde WordPress evitando el uso de Template Tags (funciones que ayudan a crear themes) o plugins que pueden hacerse desde su core. Además, puede ser totalmente ineficaz si no tenemos especial cuidado en la gestión de la base de datos. Deshabilitar el motor innodb o los logs pueden ahorrarnos mucha carga en el servidor. Pero no nos libra de tener que hacer una optimización en los valores de query_cache, por ejemplo.

Es importante también prestar especial atención en la actualización del propio CMS. Algo que puede efectuar cambios en el esquema de base de datos y mantener funcionalidades obsoletas, especialmente con plugins o funciones que se sigan usando. Plugins como WP SuperCache, basado en WP Cache 2 de Gallir, reducen los accesos de datos a MySQL. Pero en algunos casos se han encontrado problemas que venían arrastrándose desde versiones atrás.

El problema de los plugins

En un caso concreto nos hemos peleado con algún WordPress que hacía consultas antes de lanzar la acción init, que es la acción que activa plugins como WP SuperCache. Esto hacía ineficaz toda posibilidad de cacheo a través de plugins. Podríamos evitar esta situación cacheando todo el sitio en archivos estáticos HTML, a través de módulos memcached o en el servidor web, usando sistemas de proxy caché tipo Squid.

Este tipo de cosas hay que hacerlas después de asegurarse de que la la aplicación web está optimizada. O al menos no abusa demasiado de la base de datos. Más que nada porque este tipo de soluciones conllevan una serie de costes asociados. Por ejemplo, si optamos por cachear todo a disco necesitaremos, en sitios web con medio o alto tráfico, disco SAS a 10k o 15k revoluciones. Para así evitar los cuellos de botella que tendríamos con discos SATA. Muchos proveedores venden esto como «un servidor más grande», nosotros preferimos abordarlo de otra forma.

Hay otras situaciones en las que un sólo plugin puede ser el culpable de problemas de rendimiento. Muchas veces se confía demasiado en el buen hacer de los desarrolladores de plugins muy utilizados como el All In One Seo Pack, que resulta no ser tan óptimo como cabría esperar.

Nuestro trabajo

Empezamos por hacer un diagnóstico de la aplicación web. Si se trata de WordPress, limpiamos el theme y los plugins desactualizados. Además de comprobar el estado de la base de datos y desarrollar plugins o themes que utilicen la última versión de la API. Si fuese necesario, también buscaríamos soluciones a nivel de sistema que mejoren el rendimiento de la aplicación.

Estas soluciones van desde realizar optimizaciones del servidor web o en la base de datos; a implantar soluciones de caché en memoria, como opcode caché para PHP. Así como distribuir el contenido estático del blog entre varios servidores o servicios de terceros. Para soluciones más avanzadas o sitios web de gran cantidad de datos y tráfico es mejor optar por servidores cloud.

Diferentes soluciones

No siempre una solución puede ser la cura a todas las enfermedades. Por ejemplo, un tipo de motor de almacenamiento en MySQL frente a otro, como myisam frente a innodb, es más rápido en lectura. Pero esto no siempre es así. También se pueden ver casos como que una solución memcached proporciona menos rendimiento que otro servidor de base de datos. O que cachear en disco penalice mucho más que almacenar en la base de datos. No se pueden tratar todos los problemas por igual en casos de rendimiento web.

Hemos tenido alguna experiencia con clientes que, teniendo un servidor dedicado saturado, se han pasado a un servidor cloud. Así, con solo algunos cambios en el CMS, se han ahorrado bastante dinero al mes en hardware.

Problema con SFTP en OpenSUSE x64

Publicado enSistemas TI

OpenSUSE x64 es una de las múltiples distribuciones de SUSE Linux; una que además cuenta con la colaboración de AMD en su desarrollo, además de un mantenimiento basado en GNU. Actualmente OpenSUSE funciona como una comunidad de ámbito mundial que se encarga de promover el uso del sistema operativo Linux. Por ello, se considera a la distribución como una de las mejores para trabajar en equipo, de forma totalmente transparente y amigable con la comunidad open source.

En relación al control del proyecto, este recae en su totalidad en la comunidad que hay alrededor de openSUSE. Desde los probadores de las nuevas funcionalidades, escritores, los especialistas en usabilidad a cada uno de los desarrolladores que forman parte del proyecto. Todo ello hace que en el proyecto se junten profesionales con experiencia de todos los niveles, cuyas lenguas maternas nada tienen que ver e incluso distintos desde un punto de vista cultural. Y esa es la magia del código abierto.

En las nuevas versiones de openSuse x64 es habitual encontrarnos con problemas relaciondos con el protocolo SFTP. Estos se deben, generalmente, a un problema en la configuración del sshd_config. Por ello, es posible que el error que se obtengas al intentar acceder a tu servidor sea similar al que te mostramos a continuación:


sshd[25558]: error: subsystem: cannot stat /usr/lib/sftp-server: No such file or directory

Solución al problema con SFTP en openSuse x64

La solución a esta incidencia en el servidor es mucho más sencilla de lo que en un primer momento pueda parecer. Si quieres que openSUSE x64 vuelva a funcionar de la forma correcta; solo tienes que localizar el lugar en el que se encuentra el archivo «sftp-server». Una vez allí, busca la ruta en el sshd_config y procede a corregirla. En caso de que no sepas dónde se ubica el archivo, puedes utilizar la línea de comandos para dar con él de la forma más simple. Para ello, utiliza el siguiente script:


find / -name sftp-server

En nuestro caso la ubicación del archivo se encuentra en la ruta /usr/lib64/ssh/sftp-server

Para arreglar el problema basta con hacer un enlace simbólico al archivo como el siguiente:


ln -s /usr/lib64/ssh/sftp-server /usr/lib/sftp-server

Si lo prefieres, también puedes optar por localizar la siguiente línea en el sshd_config y proceder a corregirla:


Subsystem sftp /usr/lib/sftp-server

Finalmente, tendrás que reiniciar el servicio sshd para que se apliquen los cambios introducidos y que se solucione el problema.

Hace unas semanas también hablamos sobre openSUSE. Así que, si te interesa saber cómo instalar LAMP en opensuse 11.2 te enseñamos a hacerlo. Y, si estás interesando en  cualquier otro tema de programación, no dudes en consultar nuestro blog tecnológico.

Plesk 9.x rompe Yast2

Publicado enSistemas TI

Si estás utilizando YaST, la aplicación para la distribución de Linux openSUSE que facilita la adminsitración de un sistema y la instalación de software, es posible que su uso te cause algún que otro problema. Especialmente cuando tratas de instalar Plesk 9.x sobre openSUSE. Es decir, que al tratar de realizar una instalación de Plesk, la ejecución de YaST2 fallará sobre el panel de control.

Lo más probable es que al realizar tal acción te encuentres con un error similar al fragmento de código que te mostramos a continuación:

# yast
//sbin/yast: line 27: //lib/YaST2/bin/yast2-funcs: No such file or directory
//sbin/yast: line 250: set_lang_from_sysconfig: command not found
//sbin/yast: line 279: check_ncurses: command not found
package yast2-qt is not installed
package yast2-gtk is not installed
Something is wrong with the YaST user interface.

Aunque por el momento este error no cuenta con una solución definitiva, es posible realizar algunas modificaciones como solución provisional. Para evitar la aparición de este tipo de mensajes, a continuación te mostramos qué es lo que puedes hacer.

Cómo puedes arreglar el problema de YaST

Al intentar instalar el panel de control Plesk sobre la distribución de openSUSE, Plesk acostumbra a modificar $PATH. Generalmente, el panel de control suele añadir, de forma incorrecta, una doble barra que terminará siendo la causante del error. Para solucionar este problema, basta con quitar dicha barra y, seguidamente, comprobar que todo funciona de la forma correcta. Para ello, tendrás que hacer lo que te indicamos en las siguientes líneas de código:

export PATH=/sbin:/bin:/sbin:/usr/sbin:/usr/local/sbin:/root/bin:/usr/local/bin:/usr/bin:/bin:/usr/X11R6/bin:/usr/games:/usr/lib/mit/bin:/usr/lib/mit/sbin

Obviamente, lo anterior no es la solución ideal; ya que tan solo es un pequeño parche que sirve de solución al problema de forma momentánea. Es decir, que solo funcionará mientras tengamos la sesión de Plesk abierta y que se perderá cuando salgamos de nuestra suscipción en Plesk. para que se conserven estos cambios que acabamos de introducir; es decir para que se mantengan cuando cerremos sesión, lo que tenemos que hacer es meterlo en el .bashrc. De esta forma incluso cuando cerremos nuestra sesión en el panel de control, las modificaciones que hemos introducido para solucionar el problema de YaST seguirán siendo válidas.

Para ello, deberemos realizar lo siguiente:

echo 'export PATH=/sbin:/bin:/sbin:/usr/sbin:/usr/local/sbin:/root/bin:/usr/local/bin:/usr/bin:/bin:/usr/X11R6/bin:/usr/games:/usr/lib/mit/bin:/usr/lib/mit/sbin' >> ~/.bashrc

Este problema es un bug que afecta a las versiones 9.0, 9.1, 9.2 y 9.3 de Plesk. Un error que, casi con total seguridad, quedará arreglado en la próxima actualización del panel de control; haciendo que no sea necesaria realizar ninguna modificación en el código.

Virtualizando SQL Server 2008 sobre Hyper-V R2

Publicado enSistemas TI

Si vas a virtualizar un entorno SQL Server 2008, es recomendable que tengas en cuenta los siguientes aspectos:

Los diferentes tipos de discos

  • De espacio fijo. En SQL Server 2008 es muy importante el I/O (entrada y salida) de los volúmenes con los que se está trabajando. Por ello, nuestra recomendación es utilizar siempre discos de espacio fijos para guardar toda la información.
  • Controladora SCSI. Al igual que sucede en los entornos físicos, en un entorno virtual sólo podremos colocar hasta 4 discos IDE. Por lo que si necesitamos más discos lo mejor es utilizar un bus SCSI que permita el almacenamiento de los datos.
  • Usar varios VHD. Es decir, uno para el propio sistema y los archivos de instalación de SQL; otro para tempdb, otro para los logs, otro para los datos… Esto, al igual que en un entorno real permite mejorar el I/O, sobre todo si disponemos de una cabina y dedicamos discos separados (spindles) o LUN para mejorar aún más el I/O. Incluso en el caso de que no dispongamos de discos separados sigue siendo recomendable utilizar diferentes VHDs como forma de almacenamiento de la información.
  • Sistema de archivos. NTFS con unidad de asignación a 64 K; ya que esta tecnología nos permitirá obtener un mejor rendimiento.

El tipo de red

  • Es importante que la red sea Gigabit y que la velocidad haya sido configurada en full-duplex.
  • Siempre que sea posible usaremos los adaptadores sintéticos que usan los Servicios de Integración instalados en la máquina virtual para funcionar. Este tipo de dispositivos ofrecen mucho mejor rendimiento que los dispositivos emulados. Estos últimos sólo son útiles por razones de compatibilidad en sistemas que no soportan los Servicios de Integración (anteriores a MS Windows Server 2003 R2, kernels de Linux no soportados, etc…).
  • Si es posible usar teaming para mejorar el rendimiento y ofrecer redundancia. Algo que es especialmente interesante para realizar conexiones a una cabina vía iSCSI.

Memoria de la máquina virtual

La memoria se comporta exactamente igual en un entorno virtual que dentro de una máquina física. A diferencia de otros hypervisores, en Hyper-V no se permite el sobreuso (aunque MS ya está trabajando en ello); por lo que la cantidad asignada a una máquina virtual (VM) se reserva en el nodo anfitrión por completo. Recuerda que es importante dejar al propio nodo anfitrión un mínimo de 2 GB libres para que puedan ejecutarse correctamente el sistema y cada una de sus tareas.

Si sigues estos apuntes no debería haber ningún problema para virtualizar un entorno SQL Server sobre Hyper-V.

Tecno-amig@, ¿ya sabes cómo usar Hyper-V con un adaptador de red inalámbrico?

Crear una consulta select count a una select con PHP

Publicado enDesarrollo y Programación

Es posible que en alguna situación concreta necesitemos hacer una consulta del tipo select count. Algo que es especialmente útil cuando queremos hacer listados con consultas que tienen muchos elementos; como joins, condiciones where, orders o similares. También es posible que lo que quieras sea realizar en el sitio web sea una paginación. En este caso, además de realizar las consultas correspondientes, será necesario que posteriormente cachees cada una de ellas.

Cada vez que generamos este tipo de consulta select count de forma dinámica, lo habitual es que hagamos un count contra una subquery. Una subquery que sea esa misma consulta pero a la que le quitaremos todos los limits. Algo parecido al script que te mostramos a continuación y cuyo uso, en este momento, está totalmente desaconsejado:


SELECT count(*) FROM ( SELECT ...la query sin los limits) as tuplas

Consulta select count

Esto puede ocasionar serios problemas de rendimiento, sobre todo si la consulta contiene, por ejemplo, cláusulas de tipo ORDER. Para mejorar esto podemos recurrir al uso de las funciones strrpos y substr de PHP. Unas funciones que se encargan de encontrar cuál es la última coincidencia dentro de una cadena o cuál es el carácter en una cadena que nos ha sido dada. Una vez que las funciones han localizado esta coincidencia, la cadena se partirá en función de los límites que hayamos establecido previamente. El uso de estas funciones nos permiten tener una consulta count para nuestra query principal, sin tener que reescribir lo mismo dos veces.

Para ello, en primer lugar, tenemos que eliminar todos los caracteres en una cadena contenida en la $query. Desde el principio hasta la última coincidencia que se encuentre de la palabra ORDER. Es decir, contando desde el principio hasta el final de una misma cadena. Recurrir a este tipo de funciones hará que se elimine de la query original los últimos ORDERs y LIMITs. Algo similar al script que te mostramos a continuación:


*/ $count_query = substr($query,0,strrpos($query,"ORDER"));

Seguidamente, deberemos eliminar desde el principio de la query hasta el último FROM que se haya encontrado al hacer uso de dichas funciones. Es decir, algo como lo siguiente:


*/ $count_query = substr($count_query,strrpos($count_query,"FROM"),strlen($count_query));

Finalmente, tendremos que agregar la sentencia COUNT a la query. Para ello, puedes recurrir a un script como el que te mostramos a continuación:


*/ $count_query = "SELECT COUNT(*) as total ".$count_query;

De esta forma, la creación de este tipo de consultas en PHP se realizará de una forma mucho más limpia y, sobre todo, ordenada. Todo ello sin que el rendimiento de la web o del servidor pueda verse afectado.

Ejecutar código SQL nativo en Doctrine

Publicado enDesarrollo y Programación

En ocasiones es posible que necesitemos optimizar ciertas consultas SQL. Otras, simplemente, hacer querys algo complejas; incluso es posible que tengamos que lidiar con el código DQL para generar una determinada query. Y en la gran mayoría de las ocasiones, estas acciones pueden llevarnos demasiado tiempo. Para evitarlo, contamos con la posibilidad de ejecutar código nativo desde Doctrine. En este caso, SQL nativo en Doctrine.

El código nativo es el lenguaje que permite el funcionamiento de una máquina. Un lenguaje que puede crearse de dos formas diferentes. Por un lado, es posible desarrollar código nativo para microprocesadores de fácil funcionamiento: Pero, por otra parte, también puede recurrirse al código nativo como código fuente ya compilado y listo para ser utilizado por una determinada máquina. De esta forma, optimizaremos el tiempo que lleva la realización de una consulta a la base de datos.

Cómo ejecutar SQL nativo

Para ejecutar SQL nativo y reducir al máximo el tiempo para realizar una consulta SQL, puedes recurrir a una serie de scripts que te permitan realizar las tareas necesarias.

Empezaremos, en primer lugar, por definir la consulta que vamos a realizar. Para, a continuación, recuperar el singleton de la conexión. El singleton no es más que un patrón de diseño que nos permitirá crear los diferentes objetos que pertenecen a la misma clase o valor de los elementos que componen la base de datos. Su objetivo es asegurar que la clase solo tenga una única instancia y facilitar un punto de acceso de tipo global a la clase.

Una vez realizadas las configuraciones necesarias, pasaremos a ejecutar la consulta. Finalmente, recuperaremos las tuplas de resultados; es decir, una lista ordenada de los elementos que componen las clases.

A continuación, te indicamos cuáles son los scripts que tienes que utilizar para realizar cada una de las tareas necesarias para la ejecución de código nativo SQL desde Doctrine.

//definimos la consulta
$query = "select id from tabla";

//recuperamos el singleton de la conexión
$con = Doctrine_Manager::getInstance()->connection();

//ejecutamos la consulta
$st = $con->execute($query);

//recuperamos las tuplas de resultados
$rs = $st->fetchAll();

Una vez realizado esto, ya podríamos empezar a ejecutar SQL de forma nativa, optimizando así nuestro código. Y, sobre todo, facilitándonos la escritura de nuevo código.

Teniendo en cuenta el tiempo que, en muchas ocasiones, lleva la ejecución de determinadas tareas; unido a las facilidades que ofrece un código ordenado, utilizar este método es todo un acierto. A partir de ahora, solucionar problemas en el código o las bases de datos no solo será más sencillo, sino que requerirá de un tiempo mucho menor.

Internacionalizar WordPress con WPML

Publicado enDesarrollo y Programación

La internacionalización resulta algo crítico hoy en día para los medios de comunicación online. Básicamente, porque se basan mayormente en aplicaciones web. La plataforma CMS más usada en internet es sin duda WordPress, aplicación web que desde hace años cuenta con soporte i18n para sus themes y funciones internas. Y el problema siempre ha estado en la i18n del contenido. Aunque muchos nos basábamos en filtrar por un tag determinado que representase la cultura del post o página que el usuario solicitase, las cosas han evolucionado considerablemente. Gracias a la dedicación e innovación de algunos profesionales en el sector de las traducciones online, en este momento contamos con herramientas como WPML.

WordPress WPML, el plugin para solicitar traducciones de contenido

Esta herramienta nos permite traducir el theme de un sitio web; asimismo, podemos separar y asociar el contenido en base a su idioma o cultura de una forma muy sencilla. Esta separación tiene en cuenta las URLs del sitio web, que pueden ser mediante subdirectorios o subdominios dinámicos. Ten en cuenta que las traducciones automáticas para cada idioma se pueden configurar mediante el selector de idiomas a través del panel de administración.

WPML es, además, un servicio online. Un plugin que nos permite solicitar una traducción del contenido que queremos publicar a un idioma específico, hecho por un traductor nativo en ese idioma. Por lo que el cometido de WPML para internacionalizar la marca se cumple de maravilla. En tu sitio web, dispones de themes de ejemplo para poder estudiar cómo trabaja el plugin WPML. En realidad, basta con respetar el motor de i18n de WordPress a la hora de desarrollar el theme.

No hay nada como una herramienta hecha por y para profesionales de su sector. Esto es, temas y plugins que nacen con el objetivo de satisfacer las necesidades de cada uno de los proyectos. Y, en este caso, WPML es de los mejores para realizar traducciones en tu WordPress multisite o multilingüe. Tus sitios webs estarán perfectamente traducidos y orientados a diferentes públicos o países.

Administración WordPress total

En Linube, si te interesa delegar la gestión integral de tu site, también ofrecemos administración para tu WordPress. Confía en Linube y delega en nosotros las responsabilidades de gestión de tu cms. Nos encargamos de todo: desde la instalación de tu wordpress hasta la administración de sistemas informáticos. Si necesitas más información al respecto, puedes contactar siempre que quieras con nosotros; ya sea vía correo electrónico o por teléfono.

Además, puedes visitar nuestro perfil como colaborador de WPML en su sitio web, junto con algunos de los proyectos que hemos realizado utilizando este plugin. Sin duda la aparición de WPML nos facilita en gran medida la creación de sitios web en diversos idiomas.

Desarrollo con Symfony, Doctrine y MySQL Workbench

Publicado enDesarrollo y Programación

Desde hace ya unos cuantos años, en el desarrollo de aplicaciones web se tiende a utilizar herramientas que contribuyen no a que trabajemos más rápido, sino más ágil. Como es el caso de desarrollo con Symfony o Doctrine, entre otras. Ya no tiene sentido contar con grandes equipos de desarrollo. De hecho, el nivel de productividad de un equipo formado por programadores y analistas suele verse afectado negativamente cuanta más cantidad de personas estén involucradas en el proyecto.

Normalmente las aplicaciones web conllevan un montón de tareas que son repetitivas o que pueden abstraerse o automatizarse. Conseguir reducir el tiempo que necesitamos invertir para realizar dichas tareas es clave para conseguir ser productivos.

Al igual que en otros lenguajes de programación como Ruby, Python o C#, en PHP disponemos de varios frameworks diseñados para conseguir reducir estas tareas. Además, ofreciéndonos una plataforma de calidad, compatible con TDD y centrada en ofrecernos arquitecturas REST. Todas ellas cosas claves en aplicaciones web.

De entre los frameworks más serios se encuentran Symfony y Zend Framework. Ambos de una calidad y documentación extraordinaria. Symfony tiene la ventaja de contar con una comunidad muy fuerte de desarrolladores en España. Además de casos de éxito tan rotundos como Yahoo Answers, Daily Motion y Delicious.

Además permite contar con un potente y seguro motor para desarrollar formularios, un sistema de enrutamiento muy avanzado fácilmente internacionalizable, una arquitectura extensible por diseño, y la posibilidad de usar módulos de otras plataformas con Zend Framework o los nuestros propios. Por si fuera poco, los creadores de symfony han desarrollado su propio orm llamado Doctrine. Una aplicación que podemos utilizar para atacar a cualquier base de datos cuyo cliente sea compatible con PDO de PHP.

Doctrine viene por defecto con Symfony, pero también podemos usar la genial alternativa Propel. Que personalmente nos permite hacer de forma mucho más elegante la i18n.

Como todo desarrollador con experiencia sabe, el crear el modelo de base de datos para nuestra aplicación y las clases que van a permitirnos operar con ellas, es la parte que probablemente conlleve más tareas automatizables o potencialmente abstraibles. Por ello, es muy importante el uso de un orm que nos automatice todo el trabajo.

Cabe destacar que para muchos programadores esto puede parecer un error; ya que a veces solemos preocuparnos demasiado pronto por temas de rendimiento cuando en realidad deberíamos preocuparnos por terminar unas cuantas fases previas… Que son las etapas que realmente nos van a permitir tener el proyecto online con calidad en un tiempo aceptable.

Desarrollo con Symfony. Creando el modelo

Como la mayoría de cosas en symfony, para crear nuestro modelo podemos hacerlo mediante un archivo de configuración yaml. Este archivo se llama schema.yml y se ubica en el directorio config/doctrine. Siendo relativo a todas las aplicaciones de nuestro proyecto symfony. La sintaxis es bastante comprensible y nos permite de una forma limpia y sencilla representar nuestro modelo de datos.


---
detect_relations: true
options:
  collate: utf8_general_ci
  charset: utf8
  type: InnoDB

User:
  columns:
    user_id:
      type: integer(4)
      primary: true
      notnull: true
      autoincrement: true
    name:
      type: string(45)
      notnull: true
    email:
      type: string(90)
      unique: true
      notnull: true
    bornDate:
      type: timestamp
      notnull: true
  options:
    charset: utf8
    collate: utf8_general_ci

Desarrollo con Symfony; segunda parte

Este archivo de configuración nos permite tener un esquema fácilmente mantenible. Y  permitirá a symfony automatizar las tareas de creación del código sql para crear la base de datos. Además de todas las clases php que usaremos para trabajar con la misma.


#creamos el código sql encargado de crear la base de datos
php symfony doctrine:build-sql

#creamos las clases php para trabajar con esta base de datos
php symfony doctrine:build-model

Esto nos ha ahorrado una cantidad increíble de tiempo, que tendríamos que haber invertido en tareas que en principio no son costosas en complejidad pero si en tiempo.

Vemos ahora cómo insertar un registro en la tabla que hemos creado, hacemos un select, un update y lo borramos.


//hacemos un insert en la base de datos
$user = new User();
$user-name = &amp;quot;Manolo&amp;quot;;
$user-bord_date = date(&amp;quot;d-m-Y&amp;quot;,strtotime('1974-02-11'));
$user-&gt;save();

//hacemos un update
$user-&gt;name =&amp;quot;María&amp;quot;;
$user-&gt;save();

//eliminamos el registro
$user-&gt;delete();

//hacemos un select
$q = Doctrine_Query::create()-&gt;select('u.name')-&gt;from('User u')-&gt;where(&amp;quot;u.user_id = ? &amp;quot;) ;
$items = $q-&gt;execute(array(1));

foreach($items as $item){ echo $item-&gt;name;&nbsp; }

Generando el schema.yml desde MySQL Workbench

Hasta ahora nuestro mayor trabajo a la hora de crear nuestro modelo, sin contar el tiempo que hemos invertido en pensar su diseño, ha sido crear el archivo schema.yml. Esto también se puede automatizar mediante un plugin para MySQL workbench que nos permitirá exportar nuestro diagrama e/r directamente a un archivo.yml.

desarrollo con synfony-mwb
Con nuestra tabla ahora podremos crear nuestro schema.yml desde el menú plugins/catalog. Pudiendo generar un archivo o directamente pegarlo en el portapapeles.

Hay que tener cuidado con este plugin ya que nos nombres de las clases del modelo, que represantan las tablas de nuestro modelo, las escribirá en minúsculas. Cuando por convención deberían empezar con la primera letra capitalizada.

Conclusión

Actualmente existen diferentes herramientas y técnicas que nos permiten ser muy productivos a la hora de desarrollar aplicaciones web. Como es el caso de Symfony y Doctrine.

Si quieres mantenerte informado de muchas más cosas además del desarrollo con Symfony o Doctrine, no dudes en visitar asiduamente nuestro blog tecnológico.