Cómo usar Cloud Datastore con PHP

Esta parte del instructivo de Bookshelf para PHP muestra cómo crear, leer, actualizar y borrar datos estructurados en Google Cloud Datastore.

Este documento forma parte de un instructivo de varias páginas. Para comenzar desde el principio y leer las instrucciones de configuración, dirígete a App de Bookshelf de PHP.

Configuraciones

  1. Ve al directorio getting-started-php/2-structured-data y copia el archivo settings.yml.dist:

    cp config/settings.yml.dist config/settings.yml
    
  2. Abre el archivo config/settings.yml para editarlo.

  3. Reemplaza YOUR_PROJECT_ID por el ID de tu proyecto.

  4. Configura el valor de bookshelf_backend en datastore.

  5. Guarda el archivo settings.yml y ciérralo.

Cloud Datastore es un servicio completamente administrado que se inicializa y se conecta a la app de App Engine automáticamente. No es necesario que lo configures.

Cómo instalar dependencias

En el directorio 2-structured-data, ingresa este comando.

composer install

Ejecución de la app en la máquina local

  1. Inicia un servidor web local:

    php -S localhost:8000 -t web
    
  2. En el navegador web, ingresa la siguiente dirección.

    http://localhost:8000

Ahora puedes navegar por las páginas web de la app y agregar, editar y borrar libros.

Cómo implementar la app en el entorno flexible de App Engine

  1. Implementa la app de muestra:

    gcloud app deploy
    
  2. En el navegador web, ingresa la siguiente dirección. Reemplaza [YOUR_PROJECT_ID] por el ID del proyecto:

    https://[YOUR_PROJECT_ID].appspot.com
    

    Si actualizas tu app, podrás implementar la versión actualizada mediante el mismo comando que usaste para implementar la app por primera vez. La implementación nueva crea una versión nueva de tu app y la convierte a la versión predeterminada. Las versiones anteriores de la app se conservan, al igual que sus instancias de VM asociadas. Ten en cuenta que todas estas instancias de VM y versiones de la app son recursos facturables.

    Para reducir costos, borra las versiones no predeterminadas de la app.

    Para borrar una versión de una app, haz lo siguiente:

    1. En GCP Console, dirígete a la página Versiones de App Engine.

      Ir a la página de Versiones

    2. Haz clic en la casilla de verificación junto a la versión de app no predeterminada que deseas borrar.
    3. Haz clic en el botón Borrar en la parte superior de la página para borrar la versión de la app.

    Para obtener toda la información acerca de la limpieza de los recursos facturables, consulta la sección Limpieza en el paso final de este instructivo.

    Estructura de la aplicación

    El siguiente diagrama muestra los componentes de la aplicación y la manera en que se conectan entre sí.

    Proceso y estructura de la implementación de la app de Bookshelf

    Comprensión del código

    Anteriormente, editaste el archivo settings.yml y configuraste el valor de bookshelf_backend como datastore. Esto le indica a la app que debe cargar la clase Datastore, que se define en src/DataModel/Datastore.php. La clase Datastore abarca la API de Cloud Datastore y se encarga de almacenar libros en tu base de datos de Cloud Datastore.

    Este código en controllers.php define y registra un controlador para la ruta GET '/books/'. La variable $model es una instancia de la clase Datastore. El método $model->listBooks muestra un arreglo que contiene un arreglo de libros y un cursor. Luego, el motor de plantillas Twig procesa la lista de libros según la plantilla list.html.twig:

    $app->get('/books/', function (Request $request) use ($app) {
        /** @var DataModelInterface $model */
        $model = $app['bookshelf.model'];
        /** @var Twig_Environment $twig */
        $twig = $app['twig'];
        $token = $request->query->get('page_token');
        $bookList = $model->listBooks($app['bookshelf.page_size'], $token);
    
        return $twig->render('list.html.twig', array(
            'books' => $bookList['books'],
            'next_page_token' => $bookList['cursor'],
        ));
    });

    Esta es la plantilla de Twig para mostrar una lista de los libros que se recuperaron de Cloud Datastore. La plantilla recibe una variable de arreglos llamada books. Muestra el título y el autor de cada libro del arreglo. Además, la plantilla recibe una variable next_page_token que determina si se muestra el botón Más:

    {% for book in books %}
    <div class="media">
      <a href="/books/{{book.id}}">
        <div class="media-left">
          <img src="http://placekitten.com/g/128/192">
        </div>
        <div class="media-body">
          <h4>{{book.title}}</h4>
          <p>{{book.author}}</p>
        </div>
      </a>
    </div>
    {% else %}
    <p>No books found</p>
    {% endfor %}

    Este código define y registra un controlador para la ruta GET '/books/{id}', en la que {id} es el ID de un libro individual. El controlador llama al método $model->read para obtener el libro especificado desde Cloud Datastore. El motor de plantillas Twig procesa el libro según la plantilla view.html.twig:

    $app->get('/books/{id}', function ($id) use ($app) {
        /** @var DataModelInterface $model */
        $model = $app['bookshelf.model'];
        $book = $model->read($id);
        if (!$book) {
            return new Response('', Response::HTTP_NOT_FOUND);
        }
        /** @var Twig_Environment $twig */
        $twig = $app['twig'];
    
        return $twig->render('view.html.twig', array('book' => $book));
    });

    La plantilla view.html.twig recibe una variable llamada book y muestra el título, la fecha de publicación, el autor y la descripción del libro:

    <div class="media">
      <div class="media-body">
        <h4 class="book-title">
          {{book.title}}
          <small>{{book.published_date}}</small>
        </h4>
        <h5 class="book-author">By {{book.author|default('Unknown', True)}}</h5>
        <p class="book-description">{{book.description}}</p>
      </div>
    </div>

    Cuando el usuario hace clic en Agregar libro, el controlador de GET /books/add muestra un formulario para ingresar el título, el autor y otros datos de un libro. Cuando el usuario hace clic en Guardar, el controlador de POST /books/add recibe el libro nuevo de la solicitud y llama a $model->create para que almacene el libro en Cloud Datastore:

    $app->get('/books/add', function () use ($app) {
        /** @var Twig_Environment $twig */
        $twig = $app['twig'];
    
        return $twig->render('form.html.twig', array(
            'action' => 'Add',
            'book' => array(),
        ));
    });
    
    $app->post('/books/add', function (Request $request) use ($app) {
        /** @var DataModelInterface $model */
        $model = $app['bookshelf.model'];
        $book = $request->request->all();
        $id = $model->create($book);
    
        return $app->redirect("/books/$id");
    });

    Esta es la plantilla del formulario de ingreso de libros:

    {% extends "base.html.twig" %}
    
    {% block content %}
    <h3>{{action}} book</h3>
    
    <form method="POST" enctype="multipart/form-data">
    
      <div class="form-group">
        <label for="title">Title</label>
        <input type="text" name="title" id="title" value="{{book.title}}" class="form-control"/>
      </div>
    
      <div class="form-group">
        <label for="author">Author</label>
        <input type="text" name="author" id="author" value="{{book.author}}" class="form-control"/>
      </div>
    
      <div class="form-group">
        <label for="published_date">Date Published</label>
        <input type="text" name="published_date" id="published_date" value="{{book.published_date}}" class="form-control"/>
      </div>
    
      <div class="form-group">
        <label for="description">Description</label>
        <textarea name="description" id="description" class="form-control">{{book.description}}</textarea>
      </div>
    
      <button id="submit" type="submit" class="btn btn-success">Save</button>
    </form>
    
    {% endblock %}

    El código de muestra incluye controladores adicionales para editar y borrar libros individuales:

    $app->get('/books/{id}/edit', function ($id) use ($app) {
        /** @var DataModelInterface $model */
        $model = $app['bookshelf.model'];
        $book = $model->read($id);
        if (!$book) {
            return new Response('', Response::HTTP_NOT_FOUND);
        }
        /** @var Twig_Environment $twig */
        $twig = $app['twig'];
    
        return $twig->render('form.html.twig', array(
            'action' => 'Edit',
            'book' => $book,
        ));
    });
    
    $app->post('/books/{id}/edit', function (Request $request, $id) use ($app) {
        $book = $request->request->all();
        $book['id'] = $id;
        /** @var DataModelInterface $model */
        $model = $app['bookshelf.model'];
        if (!$model->read($id)) {
            return new Response('', Response::HTTP_NOT_FOUND);
        }
        if ($model->update($book)) {
            return $app->redirect("/books/$id");
        }
    
        return new Response('Could not update book');
    });
    $app->post('/books/{id}/delete', function ($id) use ($app) {
        /** @var DataModelInterface $model */
        $model = $app['bookshelf.model'];
        $book = $model->read($id);
        if ($book) {
            $model->delete($id);
    
            return $app->redirect('/books/', Response::HTTP_SEE_OTHER);
        }
    
        return new Response('', Response::HTTP_NOT_FOUND);
    });
¿Te ha resultado útil esta página? Enviar comentarios: