One place for hosting & domains

      Cómo personalizar componentes de React con props


      El autor seleccionó Creative Commons para recibir una donación como parte del programa Write for DOnations.

      Introducción

      A través de este tutorial, creará componentes personalizados pasando props a su componente. Los props son argumentos que se proporcionan a un elemento JSX. Se parecen a los props HTML estándares, pero no están predefinidos y pueden tener varios tipos de datos de JavaScript, incluidos números, cadenas, funciones, matrices e incluso otros componentes de React. Sus componentes personalizados pueden utilizar props para mostrar datos o utilizar los datos para hacer que los componentes sean interactivos. Los props son un elemento clave en la creación de componentes que se adaptan a situaciones diferentes, y aprender sobre ellos le proporcionará las herramientas necesarias para desarrollar componentes personalizados que puedan manejar situaciones únicas.

      Después de añadir props a su componente, usará PropTypes para definir el tipo de datos que espera que reciba un componente. Los PropTypes son un sistema de tipo sencillo que comprueba que los datos coincidan con los tipos previstos durante el tiempo de ejecución. Sirven como documentación y como un verificador de errores que le ayudará a hacer que su aplicación sea predecible durante su escalamiento.

      Al final del tutorial, usará diferentes props para crear una aplicación pequeña que tome una matriz de datos de animales y muestre la información, incluidos el nombre común, el nombre científico, el tamaño, la dieta y datos adicionales.

      Nota: En el primer paso se establece un proyecto en blanco sobre el cual creará el ejercicio de tutorial. Si ya tiene un proyecto de trabajo y desea empezar directamente a trabajar con props, comience con el paso 2.

      Requisitos previos

      Paso 1: Crear un proyecto vacío

      En este paso, creará un nuevo proyecto usando Create React App. Luego, eliminará el proyecto de ejemplo y los archivos relacionados que se instalan al iniciar el proyecto. Por último, creará una estructura de archivos simple para organizar sus componentes.

      Para comenzar, cree un nuevo proyecto. En su línea de comandos, ejecute la siguiente secuencia de comandos para instalar un proyecto nuevo usando create-react-app​​​1​​:

      • npx create-react-app prop-tutorial

      Al finalizar el proyecto, posiciónese en el directorio:

      En una nueva pestaña o ventana de terminal, inicie el proyecto usando la secuencia de comandos de inicio de Create React App. El navegador actualizará los cambios automáticamente; deje que esta secuencia de comandos se ejecute mientras trabaja:

      Obtendrá un servidor local activo. Si el proyecto no se abrió en una ventana de navegador, puede encontrarlo en http://localhost:3000/. Si lo ejecuta desde un servidor remoto, la dirección será http://your_domain:3000.

      Su navegador se cargará con una aplicación de React sencilla incluida como parte de la aplicación de Create React App:

      Proyecto de plantilla de React

      Creará un conjunto completamente nuevo de componentes personalizados. Comenzará limpiando código de texto estándar para poder tener un proyecto vacío.

      Empiece abriendo src/App.js en un editor de texto. Es el componente root que se inserta en la página. Todos los componentes empezarán desde aquí. Puede obtener más información sobre App.js en Cómo configurar un proyecto de React con Create React App.

      Abra src/App.js con el siguiente comando:

      Verá un archivo como este:

      prop-tutorial/src/App.js

      import React from 'react';
      import logo from './logo.svg';
      import './App.css';
      
      function App() {
        return (
          <div className="App">
            <header className="App-header">
              <img src={logo} className="App-logo" alt="logo" />
              <p>
                Edit <code>src/App.js</code> and save to reload.
              </p>
              <a
                className="App-link"
                href="https://reactjs.org"
                target="_blank"
                rel="noopener noreferrer"
              >
                Learn React
              </a>
            </header>
          </div>
        );
      }
      
      export default App;
      

      Elimine la línea import logo from './logo.svg';​​​. Luego, sustituya todo en instrucción return para mostrar un conjunto de etiquetas vacías: <</>. Esto le proporcionará una página de validación que no muestra nada. El código final tendrá el siguiente aspecto:

      prop-tutorial/src/App.js

      
      import React from 'react';
      import './App.css';
      
      function App() {
        return <></>;
      }
      
      export default App;
      

      Guárdelo y salga del editor de texto.

      Por último, elimine el logo. No lo usará en su aplicación y debería eliminar los archivos que no se usen a medida que el trabajo avance. Le evitará confusiones en el futuro.

      En la ventana de la terminal, escriba el siguiente comando:

      Si observa su navegador, verá una pantalla en blanco.

      Pantalla en blanco en Chrome

      Ahora que limpió el proyecto Create React App, cree una estructura de archivos sencilla. Esto le permitirá mantener sus componentes aislados y preservar su independencia.

      Cree un directorio llamado components en el directorio src. Este contendrá todos sus componentes personalizados.

      Cada componente tendrá su propio directorio para almacenar el archivo de componentes junto con los estilos, las imágenes, si hay alguna, y las pruebas.

      Cree un directorio para App:

      Mueva todos los archivos de la App a ese directorio. Utilice el comodín, *, para seleccionar cualquier archivo que empiece con App. sin importar la extensión. Luego, utilice el comando mv para disponerlos en el directorio nuevo.

      • mv src/App.* src/components/App

      Por último, actualice la ruta de importación relativa en index.js, el componente root que inicia todo el proceso.

      La instrucción import debe apuntar al archivo App.js en el directorio App; realice el siguiente cambio resaltado:

      prop-tutorial/src/index.js

      import React from 'react';
      import ReactDOM from 'react-dom';
      import './index.css';
      import App from './components/App/App';
      import * as serviceWorker from './serviceWorker';
      
      ReactDOM.render(
        <React.StrictMode>
          <App />
        </React.StrictMode>,
        document.getElementById('root')
      );
      
      // If you want your app to work offline and load faster, you can change
      // unregister() to register() below. Note this comes with some pitfalls.
      // Learn more about service workers: https://bit.ly/CRA-PWA
      serviceWorker.unregister();
      

      Guarde el archivo y ciérrelo.

      Ahora que el proyecto está configurado, puede crear su primer componente.

      Paso 2: Crear componentes dinámicos con props

      En este paso, creará un componente llamado props, que se modificará sobre la base de la información de entrada. Los props son los argumentos que se pasan a una función o clase; sin embargo, dado que sus componentes se transforman en objetos HTML con JSX, pasará los props como si fueran atributos HTML. A diferencia de lo que sucede con los elementos HTML, puede pasar diferentes tipos de datos; desde cadenas, hasta matrices y objetos e incluso funciones.

      Aquí creará un componente que mostrará información sobre animales. Este componente tomará el nombre común y el nombre científico del animal como cadenas, el tamaño como entero, la dieta como una matriz de cadenas y la información adicional como un objeto. Pasará la información al nuevo componente como props y consumirá esa información en su componente.

      Al final de este paso, dispondrá de un componente personalizado que consumirá props diferentes. También usted reutilizará el componente para mostrar una matriz de datos utilizando un componente común.

      Agregar datos

      Primero, necesita algunos datos de ejemplo. Cree un archivo llamado “data” en el directorio src/App.

      • touch src/components/App/data.js

      Abra el nuevo archivo en su editor de texto:

      • nano src/components/App/data.js

      A continuación, agregue una matriz de objetos que usará como datos de ejemplo:

      prop-tutorial/src/components/App/data.js

      export default [
        {
          name: 'Lion',
          scientificName: 'Panthero leo',
          size: 140,
          diet: ['meat'],
        },
        {
          name: 'Gorilla',
          scientificName: 'Gorilla beringei',
          size: 205,
          diet: ['plants', 'insects'],
          additional: {
            notes: 'This is the eastern gorilla. There is also a western gorilla that is a different species.'
          }
        },
        {
          name: 'Zebra',
          scientificName: 'Equus quagga',
          size: 322,
          diet: ['plants'],
          additional: {
            notes: 'There are three different species of zebra.',
            link: 'https://en.wikipedia.org/wiki/Zebra'
          }
        }
      ]
      

      La matriz de objetos contiene diferentes datos y le brindará la oportunidad de probar varios props. Cada objeto es un animal diferente con nombre de animal, nombre científico, tamaño, dieta y un campo opcional llamado additional, que contendrá enlaces o notas. En este código, también exportó la matriz como default.

      Guarde el archivo y ciérrelo.

      Crear componentes

      A continuación, cree un componente marcador de posición llamado AnimalCard. Llegado el momento, este componente tomará props y mostrará los datos.

      Primero, cree un directorio en src/components llamado AnimalCard y luego aplique touch a un archivo llamado src/components/AnimalCard/AnimalCard.js​ ​​y a un archivo CSS llamado src/components/AnimalCard/AnimalCard.css.

      • mkdir src/components/AnimalCard
      • touch src/components/AnimalCard/AnimalCard.js
      • touch src/components/AnimalCard/AnimalCard.css

      Abra AnimalCard.js en su editor de texto:

      • nano src/components/AnimalCard/AnimalCard.js

      Añada un componente básico que importe la CSS y muestre una etiqueta <h2>.

      prop-tutorial/src/components/AnimalCard/AnimalCard.js

      import React from 'react';
      import './AnimalCard.css'
      
      export default function AnimalCard() {
        return <h2>Animal</h2>
      }
      

      Guarde el archivo y ciérrelo. Ahora, debe importar los datos y el componente en su componente base App.

      Abra src/components/App/App/App.js:

      • nano src/components/App/App.js

      Importe los datos y el componente y, luego, realice un bucle con los datos que muestran el componente para cada elemento en la matriz:

      prop-tutorial/src/components/App/App.js

      import React from 'react';
      import data from './data';
      import AnimalCard from '../AnimalCard/AnimalCard';
      import './App.css';
      
      function App() {
        return (
          <div className="wrapper">
            <h1>Animals</h1>
            {data.map(animal => (
              <AnimalCard key={animal.name}/>
            ))}
          </div>
        )
      }
      
      export default App;
      

      Guarde el archivo y ciérrelo. Aquí, usted utiliza el método de matriz .map() para iterar los datos. Además de añadir este bucle, también tiene un div de ajuste con una clase que usará para aplicar estilo y una etiqueta <h1> para asignar a su proyecto.

      Cuando realice el guardado, el navegador se volverá a cargar y verá una etiqueta para cada carta.

      Proyecto React en el navegador sin estilo

      A continuación, añada estilo para alinear los elementos. Abra App.css:

      • nano src/components/App/App.css

      Sustituya el contenido por lo siguiente para organizar los elementos:

      prop-tutorial/src/components/App/App.css

      .wrapper {
          display: flex;
          flex-wrap: wrap;
          justify-content: space-between;
          padding: 20px;
      }
      
      .wrapper h1 {
          text-align: center;
          width: 100%;
      }
      

      Esto utilizará flexbox para reorganizar los datos, de modo que los alinee. El padding da algo de espacio en la ventana del navegador. justify-content distribuirá el espacio adicional entre elementos y .wrapper h1 dará a la etiqueta Animal el ancho completo.

      Guarde el archivo y ciérrelo. Cuando lo haga, el navegador se actualizará y verá algunos datos espaciados.

      Proyecto de React en el navegador con datos espaciados

      Agregar props

      Ahora que configuró sus componentes, puede añadir su primer prop. Al hacer un bucle con sus datos, tuvo acceso a cada objeto en la matriz data y los elementos que contiene. Añadirá cada parte de los datos a un prop separado que luego usará en su componente de AnimalCard.

      Abra App.js:

      • nano src/components/App/App.js

      Añada un prop name a AnimalCard.

      prop-tutorial/src/components/App/App.js

      import React from 'react';
      ...
      function App() {
        return (
          <div className="wrapper">
            <h1>Animals</h1>
            {data.map(animal => (
              <AnimalCard
                key={animal.name}
                name={animal.name}
              />
            ))}
          </div>
        )
      }
      
      export default App;
      

      Guarde el archivo y ciérrelo. El prop name tiene el aspecto de un atributo HTML estándar; sin embargo, en lugar de una cadena usted pasará la propiedad name del objeto animal entre llaves.

      Ahora que pasó un prop para el nuevo componente, necesita usarlo. Abra AnimalCard.js:

      • nano src/components/AnimalCard/AnimalCard.js

      Todos los props que pasa al componente se recopilan en un objeto que será el primer argumento de su función. Desestructure el objeto para extraer props individuales:

      prop-tutorial/src/components/AnimalCard/AnimalCard.js

      
      import React from 'react';
      import './AnimalCard.css'
      
      export default function AnimalCard(props) {
        const { name } = props;
        return (
          <h2>{name}</h2>
        );
      }
      

      Tenga en cuenta que no necesita desestructurar un prop para usarlo, pero que este es un método útil para gestionar los datos de ejemplo de este tutorial.

      Después de desestructurar el objeto, puede utilizar los componentes individuales de datos. En este caso, usará el título en una etiqueta <h2>, rodeando el valor con llaves para que React sepa que debe evaluarlo como JavaScript.

      También puede utilizar una propiedad en el objeto prop con notación de puntos. Como ejemplo, puede crear un elemento <h2> como este:<h2>{props.title}</h2>. La ventaja de la desestructuración es que puede recopilar props no utilizados y emplear el operador rest de objetos.

      Guarde el archivo y ciérrelo. Cuando lo haga, el navegador se volverá a cargar y verá el nombre específico de cada animal en lugar de un marcador de posición.

      Proyectos React con nombres de animales representados

      La propiedad name es una cadena, pero un prop puede ser cualquier tipo de datos que pueda pasar a una función JavaScript. Para ver esto en funcionamiento, añada el resto de los datos.

      Abra el archivo App.js:

      • nano src/components/App/App.js

      Añada un prop para cada uno de los siguientes: scientificName, size, diet y additional. Se incluyen cadenas, enteros, matrices y objetos.

      prop-tutorial/src/components/App/App.js

      import React from 'react';
      ...
      
      function App() {
        return (
          <div className="wrapper">
            <h1>Animals</h1>
            {albums.map(album => (
              <AnimalCard
                additional={animal.additional}
                diet={animal.diet}
                key={animal.name}
                name={animal.name}
                scientificName={animal.scientificName}
                size={animal.size}
              />
            ))}
          </div>
        )
      }
      
      export default App;
      

      Debido a que creará un objeto, puede añadirlo en cualquier orden que desee. La alfabetización hace que sea más fácil examinar una lista de props, en especial en una lista más grande. También puede añadirlos en la misma línea, pero al separarlos uno en cada línea se preserva la legibilidad.

      Guarde y cierre el archivo. Abra AnimalCard.js.

      • nano src/components/AnimalCard/AnimalCard.js

      Esta vez, desestructure las props de la lista del parámetro de función y utilice los datos del componente:

      prop-tutorial/src/components/AnimalCard/AnimalCard.js

      import React from 'react';
      import './AnimalCard.css'
      
      export default function AnimalCard({
        additional,
        diet,
        name,
        scientificName,
        size
      }) {
        return (
          <div>
            <h2>{name}</h2>
            <h3>{scientificName}</h3>
            <h4>{size}kg</h4>
            <div>{diet.join(', ')}.</div>
          </div>
        );
      }
      

      Después de extraer los datos, puede añadir scientificName y size en las etiquetas de encabezado, pero deberá convertir la matriz en una cadena para que React pueda mostrarla en la página. Puede hacerlo con join(', '), lo cual creará una lista separada con comas.

      Guarde y cierre el archivo. Cuando lo haga, el navegador se actualizará y verá los datos estructurados.

      Proyecto de React con animales con datos completos

      Puede crear una lista similar con el objeto additional y, en su lugar, añadir una función para alertar al usuario con los datos. Esto le dará la oportunidad de pasar funciones como props y, luego, utilizar datos dentro de un componente cuando invoque una función.

      Abra App.js:

      • nano src/components/App/App.js

      Cree una función llamada showAdditionalData que convertirá el objeto en una cadena y la mostrará como una alerta.

      prop-tutorial/src/components/App/App.js

      import React from 'react';
      ...
      
      function showAdditional(additional) {
        const alertInformation = Object.entries(additional)
          .map(information => `${information[0]}: ${information[1]}`)
          .join('n');
        alert(alertInformation)
      };
      
      function App() {
        return (
          <div className="wrapper">
            <h1>Animals</h1>
            {data.map(animal => (
              <AnimalCard
                additional={animal.additional}
                diet={animal.diet}
                key={animal.name}
                name={animal.name}
                scientificName={animal.scientificName}
                showAdditional={showAdditional}
                size={animal.size}
              />
            ))}
          </div>
        )
      }
      
      export default App;
      

      La función showAdditional convierte el objeto en una matriz de pares en la cual el primer elemento es la clave y el segundo el valor. Luego asigna los datos convirtiendo el par de claves en una cadena. Luego los une con un salto de línea n antes de pasar la cadena completa a la función de alerta.

      Debido a que JavaScript puede aceptar funciones como argumentos, React también puede aceptar funciones como props. Por lo tanto, puede pasar showAdditional a AnimalCard como un prop llamado showAdditional.

      Guarde y cierre el archivo. Abra AnimalCard:

      • nano src/components/AnimalCard/AnimalCard.js

      Retire la función showAdditional del objeto props y cree un <button> con un evento onClick que invoque la función con el objeto additional:

      prop-tutorial/src/components/AnimalCard/AnimalCard.js

      import React from 'react';
      import './AnimalCard.css'
      
      export default function AnimalCard({
        additional,
        diet,
        name,
        scientificName,
        showAdditional,
        size
      }) {
        return (
          <div>
            <h2>{name}</h2>
            <h3>{scientificName}</h3>
            <h4>{size}kg</h4>
            <div>{diet.join(', ')}.</div>
            <button onClick={() => showAdditional(additional)}>More Info</button>
          </div>
        );
      }
      

      Guarde el archivo. Cuando lo haga, el navegador se actualizará y verá un botón después de cada tarjeta. Cuando haga clic en el botón, obtendrá una alerta con los datos adicionales.

      Alerta con información

      Si intenta hacer clic en More Info para Lion, verá un error. Esto se debe a que no hay datos adicionales para el león. Verá cómo solucionarlo en el paso 3.

      Por último, añada estilo a la tarjeta de música. Añada un className de animal-wrapper al div en AnimalCard:

      prop-tutorial/src/components/AnimalCard/AnimalCard.js

      import React from 'react';
      import './AnimalCard.css'
      
      export default function AnimalCard({
      ...
        return (
          <div className="animal-wrapper">
      ...
          </div>
        )
      }
      

      Guarde y cierre el archivo. Abra AnimalCard.css:

      • nano src/components/AnimalCard/AnimalCard.css

      Añada CSS para aplicar a las tarjetas y al botón un pequeño borde y un relleno:

      prop-tutorial/src/components/AnimalCard/AnimalCard.css

      .animal-wrapper {
          border: solid black 1px;
          margin: 10px;
          padding: 10px;
          width: 200px;
      }
      
      .animal-wrapper button {
          font-size: 1em;
          border: solid black 1px;
          padding: 10;
          background: none;
          cursor: pointer;
          margin: 10px 0;
      }
      

      Este CSS añadirá un pequeño borde a la tarjeta y sustituirá el estilo predeterminado de botón por un borde y relleno. cursor: pointer cambiará el cursor cuando pase el puntero sobre el botón.

      Guarde y cierre el archivo. Cuando lo haga, el navegador se actualizará y verá los datos en tarjetas individuales.

      Proyecto React con tarjetas de animales con el estilo

      En este punto, creó dos componentes personalizados. Pasó datos al segundo componente del primer componente utilizando props. Entre los props se incluyeron diferentes datos, como cadenas, enteros, matrices, objetos y funciones. En su segundo componente, empleó los props para crear un componente dinámico utilizando JSX.

      En el siguiente paso, usará un sistema de tipos llamado prop-types para especificar la estructura que su componente prevé, lo cual aportará previsibilidad en su aplicación y evitará errores.

      Paso 3: Crear props predecibles con PropTypes y defaultProps

      En este paso, agregará un sistema de tipos ligero a sus componentes con PropTypes. PropTypes funciona como otros sistemas de tipos definiendo explícitamente el tipo de datos que espera recibir para un prop determinado. También le dan la oportunidad de definir datos predeterminados en casos en que no siempre se requiere el prop. A diferencia de la mayoría de los sistemas de tipos, PropTypes es una comprobación de tiempo de ejecución. Por ello, si los props no coinciden con el tipo, el código se compilará de todas formas, pero también mostrará un error en la consola.

      Al final de este paso, sumará previsibilidad a su componente personalizado definiendo el tipo para cada prop. Esto garantizará que la siguiente que trabaje en el componente tenga una idea clara de la estructura de los datos que el componente necesitará.

      El paquete prop-types se incluye como parte de la instalación de Create React App. Para usarlo, lo único que debe hacer es importarlo a su componente.

      Abra AnimalCard.js:

      • nano src/components/AnimalCard/AnimalCard.js

      Luego importe PropTypes desde prop-types:

      prop-tutorial/src/components/AnimalCard/AnimalCard.js

      import React from 'react';
      import PropTypes from 'prop-types';
      import './AnimalCard.css'
      
      export default function AnimalCard({
      ...
      }
      

      Añada PropTypes directamente a la función del componente. En JavaScript, las funciones son objetos; esto significa que puede añadir propiedades utilizando sintaxis de puntos. Añada los siguientes PropTypes a AnimalCard.js:

      prop-tutorial/src/components/AnimalCard/AnimalCard.js

      import React from 'react';
      import PropTypes from 'prop-types';
      import './AnimalCard.css'
      
      export default function AnimalCard({
      ...
      }
      
      AnimalCard.propTypes = {
        additional: PropTypes.shape({
          link: PropTypes.string,
          notes: PropTypes.string
        }),
        diet: PropTypes.arrayOf(PropTypes.string).isRequired,
        name: PropTypes.string.isRequired,
        scientificName: PropTypes.string.isRequired,
        showAdditional: PropTypes.func.isRequired,
        size: PropTypes.number.isRequired,
      }
      

      Guarde y cierre el archivo.

      Como puede ver, hay muchos PropTypes diferentes. Esta es solo una pequeña muestra; consulte la documentación oficial de React para ver los demás que puede utilizar.

      Comenzaremos con el prop name. Aquí, especificará que name debe ser una string. La propiedad scientificName es la misma. size es un number, que puede incluir números de punto flotante, como 1.5, y enteros, como 6. showAdditional is una función (func).

      diet, por otra parte, es un poco diferente. En este caso, especifica que diet será una array, pero también necesita especificar lo que esta matriz contendrá. En este caso, la matriz contendrá solo cadenas. Si desea mezclar tipos, puede utilizar otro prop llamado oneOfType, que toma una matriz de PropTypes válidos. Puede utilizar oneOfType en cualquier lugar. Por ello, si desea que size sea un número o una cadena, puede cambiar el parámetro por esto:

      size: PropTypes.oneOfType([PropTypes.number, PropTypes.string])
      

      El prop additional también es un poco más complejo. En este caso, especifica un objeto y, para una mayor claridad, indica lo que desea que contenga. Para hacerlo, se utiliza PropTypes.shape, que toma un objeto con campos adicionales que necesitarán sus propios PropTypes. En este caso, link y notes son PropTypes.string.

      Actualmente, todos los datos están bien formados y coinciden con los props. Para ver lo que sucede si los PropTypes no coinciden, abra sus datos:

      • nano src/components/App/data.js

      Cambie el tamaño a una cadena en el primer elemento:

      prop-tutorial/src/components/App/data.js

      export default [
        {
          name: 'Lion',
          scientificName: 'Panthero leo',
          size: '140',
          diet: ['meat'],
        },
      ...
      ]
      

      Guarde el archivo. Cuando lo haga, el navegador se actualizará y verá un error en la consola.

      Error

      index.js:1 Warning: Failed prop type: Invalid prop `size` of type `string` supplied to `AnimalCard`, expected `number`. in AnimalCard (at App.js:18) in App (at src/index.js:9) in StrictMode (at src/index.js:8)

      Navegador con error de tipo

      A diferencia de otros sistemas de tipos, como TypeScript, PropTypes no le proporcionará una advertencia en el momento de la compilación y. siempre y cuando no haya errores de código, se compilará de todas formas. Esto significa que puede publicar accidentalmente código con errores de prop.

      Restablezca el tipo correcto para los datos:

      prop-tutorial/src/components/App/data.js

      export default [
        {
          name: 'Lion',
          scientificName: 'Panthero leo',
          size: 140,
          diet: ['meat'],
        },
      ...
      ]
      

      Guarde y cierre el archivo.

      Abra AnimalCard.js:

      • nano src/components/AnimalCard/AnimalCard.js

      Cada prop, a excepción de additional, tiene la propiedad isRequired. Eso significa que se necesitan. Si no incluye un prop requerido, el código se compilará de todas formas, pero verá un error de tiempo de ejecución en la consola.

      Si no se necesita un prop, puede añadir un valor predeterminado. Siempre se recomienda añadir un valor predeterminado para evitar errores de tiempo de ejecución si no se requiere un prop. Por ejemplo, en el componente AnimalCard, invoca una función con los datos additional. Si no está allí, la función intentará modificar un objeto que no existe y la aplicación fallará.

      Para evitar este problema, añada una defaultProp para additional:

      prop-tutorial/src/components/AnimalCard/AnimalCard.js

      import React from 'react';
      import PropTypes from 'prop-types';
      import './AnimalCard.css'
      
      export default function AnimalCard({
      ...
      }
      
      AnimalCard.propTypes = {
        additional: PropTypes.shape({
          link: PropTypes.string,
          notes: PropTypes.string
        }),
      ...
      }
      
      AnimalCard.defaultProps = {
        additional: {
          notes: 'No Additional Information'
        }
      }
      

      Añada los defaultProps a la función utilizando sintaxis de puntos, como lo hizo con propTypes. Luego, agregue un valor predeterminado que debe utilizar si el prop es undefined. En este caso, se hace coincidir la forma de additional, incluido un mensaje de que no hay más información.

      Guarde y cierre el archivo. Cuando lo haga, el navegador se actualizará. Después de que se actualice, haga clic en el botón More Info para Lion. No tiene un campo additional en los datos; por lo tanto, el prop es undefined. Sin embargo, AnimalCard hará una sustitución en el prop predeterminado.

      Navegador con el mensaje predeterminado para la alerta

      Ahora, sus props estarán bien documentados y serán necesarios o tendrán un valor por defecto para garantizar la previsibilidad del código. Esto ayudará a los futuros desarrolladores (incluido usted mismo) a determinar los props que un componente necesita. Esto hará que sea más fácil intercambiar y reutilizar sus componentes proporcionando información completa sobre cómo estos usarán los datos que reciben.

      Conclusión

      En este tutorial, creó varios componentes que utilizan props para mostrar la información de un elemento principal. Los props le ofrecen la flexibilidad necesaria para comenzar a desglosar los componentes más grandes en piezas más pequeñas y con mayor concentración. Ahora que sus datos ya no están acoplados estrechamente con la información de su visualización, podrá tomar decisiones sobre cómo segmentar su aplicación.

      Los props son una herramienta crucial para crear aplicaciones complejas y dan la oportunidad de crear componentes que pueden adaptarse a los datos que reciben. Con PropTypes, crea componentes predecibles y legibles que permitirán a un equipo reutilizar el trabajo de los demás para crear una base de código flexible y estable. Si desea acceder a más tutoriales de React, consulte nuestra página temática de React o regrese a la página de la serie sobre cómo desarrollar código con React.js.



      Source link

      Cómo configurar un firewall con UFW en Ubuntu 20.04


      Introducción

      UFW, o Uncomplicated Firewall, es una interfaz de gestión de firewall simplificada que oculta la complejidad de las tecnologías de filtrado de paquetes de nivel inferior, como iptables y nftables. Si desea comenzar a proteger su red y no está seguro respecto de la herramienta que debe utilizar, UFW puede ser la mejor opción .

      En este tutorial, verá la manera de configurar un firewall con UFW en Ubuntu 20.04.

      Requisitos previos

      Para este tutorial, necesitará lo siguiente:

      UFW viene instalado por defecto en Ubuntu. Si se desinstaló por alguna razón, puede instalarlo con sudo apt install ufw​​​2​​​.

      Paso 1: Utilizar IPv6 con UFW (opcional)

      Este tutorial se redactó teniendo en cuenta IPv4, pero funcionará para IPv6 siempre que lo habilite. Si su servidor de Ubuntu tiene IPv6 habilitado, compruebe que UFW esté configurado para que admitir IPv6 de modo que administre las reglas de firewall para IPv6 además de IPv4. Para hacerlo, abra la configuración de UFW con nano o su editor favorito.

      • sudo nano /etc/default/ufw

      A continuación, asegúrese de que el valor de IPV6 sea yes. Debería tener el siguiente aspecto:

      /etc/default/ufw excerpt

      IPV6=yes
      

      Guarde y cierre el archivo. Cuando UFW esté habilitado, se configurará para escribir reglas de firewall de IPv4 y IPv6. Sin embargo, antes de habilitar UFW, nos convendrá comprobar que su firewall esté configurado para que usted pueda establecer conexión a través de SSH. Empezaremos con la configuración de las políticas predeterminadas.

      Paso 2: Configurar políticas predeterminadas

      Si recién está dando los primeros pasos con su firewall, las primeras reglas que deben definirse son sus políticas predeterminadas. Estas reglas controlan el manejo del tráfico que no coincida de forma explícita con otras reglas. Por defecto, UFW está configurado para denegar todas las conexiones entrantes y permitir todas las conexiones salientes. Esto significa que quien intente establecer conexión con su servidor no podrá hacerlo, mientras que cualquier aplicación dentro del servidor podrá llegar al mundo exterior.

      Restableceremos los valores predeterminados de sus reglas de UFW para garantizar que podamos seguir con este tutorial. Para fijar los valores predeterminados utilizados por UFW, emplee estos comandos:

      • sudo ufw default deny incoming
      • sudo ufw default allow outgoing

      Establecen los valores predeterminados para denegar las conexiones entrantes y permitir las salientes. Con solo estos valores predeterminados de firewall podría bastar para una computadora personal, pero normalmente los servidores deben responder a las solicitudes de usuarios externos. Lo veremos a continuación.

      Paso 3: Habilitar conexiones SSH

      Si habilitamos nuestro firewall de UFW ahora, denegaría todas las conexiones entrantes. Esto significa que deberemos crear reglas que permitan explícitamente las conexiones entrantes legítimas (SSH o HTTP, por ejemplo) si queremos que nuestro servidor responda a estos tipos de solicitudes. Si utiliza un servidor en nube, probablemente le convenga permitir las conexiones SSH entrantes para poder conectarse y administrar su servidor.

      Para configurar su servidor de modo que permita las conexiones SSH entrantes, puede utilizar este comando:

      Esto creará reglas de firewall que permitirán todas las conexiones en el puerto 22, que es el que escucha el demonio SSH por defecto. UFW registra el significado del puerto allow ssh porque está enumerado como servicio en el archivo /etc/services.

      Sin embargo, podemos escribir la regla equivalente especificando el puerto en vez del nombre del servicio. Por ejemplo, este comando funciona como el anterior:

      Si configuró su demonio SSH para utilizar un puerto diferente, deberá especificar el puerto apropiado. Por ejemplo, si su servidor SSH escucha en el puerto 2222 puede utilizar este comando para permitir las conexiones en ese puerto:

      Ahora que su firewall está configurado para permitir las conexiones SSH entrantes, podemos habilitarlo.

      Paso 4: Habilitar UFW

      Para habilitar UFW, utilice este comando:

      Recibirá una advertencia que indicará que el comando puede interrumpir las conexiones SSH existentes. Ya configuramos una regla de firewall que permite conexiones SSH. Debería ser posible continuar sin inconvenientes. Responda a la solicitud con y y presione ENTER.

      Con esto, el firewall quedará activo. Ejecute el comando sudo ufw status verbose para ver las reglas que se configuran. En el resto de este tutorial se abarca en mayor profundidad la forma de utilizar UFW. Se analizarán opciones como las de permitir o denegar diferentes tipos de conexiones.

      Paso 5: Habilitar otras conexiones

      En este momento, debería permitir el resto de las conexiones a las que su servidor debe responder. Las conexiones que debería permitir dependen de sus necesidades específicas. Afortunadamente, ya sabe cómo escribir reglas que permiten las conexiones basadas en un nombre de servicio o un puerto; ya lo hicimos para SSH en el puerto 22. También puede hacerlo para:

      • HTTP en el puerto 80, que es lo que utilizan los servidores web no cifrados, con sudo ufw allow http o sudo ufw allow 80
      • HTTPS en el puerto 443, que es lo que utilizan los servidores web cifrados, con sudo ufw allow https o sudo ufw allow 443

      Existen varias maneras de permitir otras conexiones, aparte de especificar un puerto o un servicio conocido.

      Intervalos de puerto específicos

      Puede especificar intervalos de puerto con UFW. Algunas aplicaciones utilizan varios puertos en vez de uno solo.

      Por ejemplo, para permitir las conexiones de X11 que utilizan los puertos 6000 a 6007, use estos comandos:

      • sudo ufw allow 6000:6007/tcp
      • sudo ufw allow 6000:6007/udp

      Al especificar intervalos de puerto con UFW, debe definir el protocolo (tcp o udp) al que deberían aplicarse las reglas. No lo mencionamos antes porque cuando no se especifica el protocolo se permiten ambos de forma automática, lo cual está bien en la mayoría de los casos.

      Direcciones IP específicas

      Al trabajar con UFW, también puede especificar direcciones IP. Por ejemplo, si desea permitir las conexiones desde una dirección IP específica, como una dirección IP de trabajo o doméstica 203.0.113.4, debe definir from y luego la dirección IP:

      • sudo ufw allow from 203.0.113.4

      También puede especificar un puerto concreto al que la dirección IP pueda conectarse agregando to any port seguido del número de este. Por ejemplo, si desea permitir que 203.0.113.4 se conecte al puerto 22 (SSH), utilice este comando:

      • sudo ufw allow from 203.0.113.4 to any port 22

      Subredes

      Si desea permitir una subred de direcciones IP, puede hacerlo utilizando la notación CIDR para especificar una máscara de red. Por ejemplo, si desea permitir todas las direcciones IP de la 203.0.113.1 a la 203.0.113.254 podría utilizar este comando:

      • sudo ufw allow from 203.0.113.0/24

      Del mismo modo, también puede especificar el puerto de destino al que puede conectarse la subred 203.013.0/24. Una vez más, utilizaremos el puerto 22 (SSH) como ejemplo:

      • sudo ufw allow from 203.0.113.0/24 to any port 22

      Conexiones a una interfaz de red específica

      Si desea crear una regla de firewall que solo se aplique a una interfaz de red específica, puede hacerlo optando por “allow in on” seguido del nombre de la interfaz de red.

      Tal vez le convenga revisar sus interfaces de red antes de continuar. Para hacerlo, utilice este comando:

      Output Excerpt

      2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state . . . 3: eth1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default . . .

      El resultado resaltado indica los nombres de la interfaz de red. Normalmente, tienen nombres similares a eth0 o enp3s2.

      Así, si su servidor tiene una interfaz de red pública llamada eth0, podría permitir el tráfico HTTP (puerto 80) hacia él con este comando:

      • sudo ufw allow in on eth0 to any port 80

      Al hacerlo permitiría que su servidor recibiera solicitudes HTTP desde la Internet pública.

      O bien, si desea que su servidor de base de datos de MySQL (puerto 3306) escuche las conexiones en la interfaz de red privada eth1, por ejemplo, podría utilizar este comando:

      • sudo ufw allow in on eth1 to any port 3306

      Esto permitiría que otros servidores de su red privada se conectaran a su base de datos de MySQL.

      Paso 6: Denegar conexiones

      Si no cambió la política predeterminada para las conexiones entrantes, UFW está configurado para denegarlas a todas. Generalmente, esto simplifica el proceso de creación de una política de firewall segura al exigirle crear reglas que permitan de forma explícita el acceso de puertos específicos y direcciones IP.

      Sin embargo, a veces le convendrá denegar conexiones específicas basadas en la dirección IP o subred de origen, quizás por saber que su servidor recibe ataques desde ellas. Además, si desea cambiar el valor su política entrante predeterminada a allow (no lo recomendamos), debería crear reglas deny para cualquier servicio o dirección IP cuyas conexiones no desee permitir.

      Para escribir reglas de deny, puede utilizar los comandos descritos anteriormente y sustituir allow por deny.

      Por ejemplo, para denegar conexiones HTTP, podría utilizar este comando:

      A su vez, si desea denegar todas las conexiones de 203.0.113.4 podría utilizar este comando:

      • sudo ufw deny from 203.0.113.4

      Ahora veremos la forma de eliminar reglas.

      Paso 7: Eliminar reglas

      Saber eliminar reglas de firewall es tan importante como saber crearlas. Existen dos maneras diferentes de especificar las reglas que se eliminarán: por número de regla o por regla real (se asemejan a la forma en que las reglas se especifican al crearse). Comenzaremos con el método de eliminación por número de regla porque es más sencillo.

      Por número de regla

      Si utiliza el número de regla para eliminar reglas de firewall, lo primero que le convendrá hacer es obtener una lista de reglas de firewall. El comando “UFW status” tiene una opción para mostrar números junto a cada regla, como se muestra aquí:

      Numbered Output:

      Status: active To Action From -- ------ ---- [ 1] 22 ALLOW IN 15.15.15.0/24 [ 2] 80 ALLOW IN Anywhere

      Si decidimos eliminar la regla 2, que permite las conexiones del puerto 80 (HTTP), podemos especificarlo en un comando “UFW delete”como este:

      Esto mostraría un mensaje de confirmación y eliminaría la regla 2, que permite conexiones HTTP. Tenga en cuenta que si tiene IPv6 habilitado, le convendría eliminar también la regla IPv6 correspondiente.

      Por regla real

      La alternativa a números de regla es especificar la regla real que se eliminará. Por ejemplo, si desea eliminar la regla allow http, podría escribir lo siguiente:

      • sudo ufw delete allow http

      También podría especificar la regla mediante allow 80 en vez de hacerlo por nombre de servicio:

      Con este método se eliminarán las reglas IPv4 y IPv6, si existen.

      Paso 8: Comprobar el estado y las reglas de UFW

      En cualquier momento, puede verificar el estado de UFW con este comando:

      Si UFW está desactivado, lo cual se aplica por defecto, verá algo como esto:

      Output

      Status: inactive

      Si UFW está activo, lo cual debería suceder si siguió el paso 3, en el resultado se indicará que está activo y se enumerará cualquier regla configurada. Por ejemplo, si el firewall está configurado para permitir conexiones SSH (puerto 22) desde cualquier parte, el resultado podría ser parecido a este:

      Output

      Status: active Logging: on (low) Default: deny (incoming), allow (outgoing), disabled (routed) New profiles: skip To Action From -- ------ ---- 22/tcp ALLOW IN Anywhere

      Utilice el comando status si desea verificar la configuración que UFW aplicó al firewall.

      Paso 9: Deshabilitar o reiniciar UFW (opcional)

      Si decide que no desea utilizar UFW, puede desactivarlo con este comando:

      Cualquier regla que haya creado con UFW dejará de estar activa. Siempre puede ejecutar sudo ufw enable si necesita activarla más adelante.

      Si ya configuró reglas de UFW y decide que desea empezar de nuevo, puede utilizar el comando “reset”:

      Con esto se desactivará UFW y se eliminará cualquier regla definida anteriormente. Tenga en cuenta que los ajustes originales de las políticas predeterminadas no se restablecerán si las modificó en algún momento. Esto debería permitirle empezar de nuevo con UFW.

      Conclusión

      De esta manera, su firewall quedará configurado para permitir conexiones SSH (al menos). Asegúrese de permitir cualquier otra conexión entrante que necesite su servidor y, al mismo tiempo, limitar cualquier conexión innecesaria, de modo que su servidor funcione y sea seguro.

      Para obtener información sobre más configuraciones comunes de UFW, consulte el tutorial Aspectos básicos de UFW: reglas y comandos comunes de firewall.



      Source link

      Cómo utilizar el tipo de datos BLOB de MySQL para almacenar imágenes con PHP en Ubuntu 18.04


      El autor seleccionó Girls Who Code para recibir una donación como parte del programa Write for DOnations.

      Introducción

      El tipo de datos de gran objeto binario (BLOB) es un tipo de datos de MySQL que puede almacenar datos binarios como los de archivos de imagen, multimedia y PDF.

      Al crear aplicaciones que requieren una base de datos estrechamente acoplada donde las imágenes deben estar sincronizadas con los datos relacionados (por ejemplo, un portal de empleados, una base de datos de estudiantes o una aplicación financiera), puede resultarle conveniente almacenar imágenes como las de fotos y firmas de pasaportes de estudiantes en una base de datos de MySQL junto con otra información relacionada.

      Aquí es donde entra el tipo de datos BLOB de MySQL. Este enfoque de programación elimina la necesidad de crear un sistema de archivos independiente para almacenar imágenes. El esquema también centraliza la base de datos, haciéndola más portátil y segura porque los datos están aislados del sistema de archivos. Crear copias de seguridad también es más sencillo, ya que que puede crear un solo archivo MySQL dump que contenga todos sus datos.

      La recuperación de datos es más rápida y, al crear registros, podrá estar seguro de que las reglas de validación de datos y la integridad referencial se preserven, en especial al utilizar transacciones en MySQL.

      En este tutorial, utilizará el tipo de datos BLOB de MySQL para almacenar imágenes con PHP en Ubuntu 18.04.

      Requisitos previos

      Para completar esta guía, necesitará lo siguiente:

      Paso 1: Crear una base de datos

      Comenzará creando una base de datos de ejemplo para su proyecto. Para hacer esto, aplique SSH a su servidor y luego ejecute el siguiente comando para iniciar sesión en su servidor MySQL como root:

      Ingrese la contraseña root de su base de datos de MySQL y presione INTRO para continuar.

      Luego, ejecute el siguiente comando para crear una base de datos. En este tutorial, lo llamaremos test_company:

      • CREATE DATABASE test_company;

      Una vez que cree la base de datos, verá el siguiente resultado:

      Output

      Query OK, 1 row affected (0.01 sec)

      Luego, cree una cuenta test_user en el servidor de MySQL y recuerde reemplazar PASSWORD por una contraseña segura:

      • CREATE USER 'test_user'@'localhost' IDENTIFIED BY 'PASSWORD';

      Verá el siguiente resultado:

      Output

      Query OK, 0 rows affected (0.01 sec)

      Para otorgar a test_user privilegios completos respecto de la base de datos test_company, ejecute lo siguiente:

      • GRANT ALL PRIVILEGES ON test_company.* TO 'test_user'@'localhost';

      Asegúrese de obtener el siguiente resultado:

      Output

      Query OK, 0 rows affected (0.01 sec)

      Por último, elimine la tabla de privilegios para que MySQL vuelva a cargar los permisos:

      Asegúrese de ver el siguiente resultado:

      Output

      Query OK, 0 rows affected (0.01 sec)

      Ahora que la base de datos test_company y test_user están listos, continúe creando una tabla products para almacenar productos de ejemplo. Más adelante, utilizará esta tabla para insertar y obtener registros a fin de demostrar cómo funciona BLOB de MySQL.

      Cierre sesión en el servidor de MySQL:

      Luego, vuelva a iniciar sesión con las credenciales de test_user que creó:

      Cuando se le solicite, ingrese la contraseña de test_user y presione ENTER para continuar. Luego, posiciónese en la base de datos test_company escribiendo lo siguiente:

      Una vez que seleccione la base de datos test_company, MySQL mostrará lo siguiente:

      Output

      Database changed

      Luego, cree una tabla products ejecutando lo siguiente:

      • CREATE TABLE `products` (product_id BIGINT PRIMARY KEY AUTO_INCREMENT, product_name VARCHAR(50), price DOUBLE, product_image BLOB) ENGINE = InnoDB;

      Con este comando se crea una tabla llamada products. La tabla tiene cuatro columnas:

      • product_id: esta columna utiliza un tipo de datos BIGINT para admitir una gran lista de productos hasta un máximo de 2⁶³-1 artículos. Se marca la columna como PRIMARY KEY para identificar productos de manera exclusiva. Para que MySQL administre la generación de nuevos identificadores para columnas insertadas, utilizó la palabra clave AUTO_INCREMENT.

      • product_name: esta columna contiene los nombres de los productos. Se utiliza el tipo de datos VARCHAR, ya que este campo generalmente administra alfanuméricos de hasta un máximo de 50 caracteres; el límite de 50 es solo un valor hipotético utilizado para de este tutorial.

      • price: para fines demostrativos, su tabla products contiene la columna price que permite almacenar el precio minorista de los productos. Dado que algunos productos pueden tener valores flotantes (por ejemplo 23.69, 45.36, 102.99), se utiliza el tipo de datos DOUBLE.

      • product_image: en esta columna se utiliza el tipo de datos BLOB para almacenar los datos binarios reales de las imágenes de los productos.

      Se utiliza el ENGINE de almacenamiento InnoDB para que la tabla admita una amplia gama de funciones, incluso transacciones de MySQL. Después de ejecutar esto para crear la tabla products, verá el siguiente resultado:

      Output

      Query OK, 0 rows affected (0.03 sec)

      Cierre la sesión de su servidor de MySQL:

      Verá el siguiente resultado:

      Output

      Bye

      La tabla products ahora está lista para almacenar algunos registros, incluidas las imágenes de los productos y, en el siguiente paso, la completará con algunos productos.

      Paso 2: Crear secuencias de comandos PHP para conectar y completar la base de datos

      En este paso, creará una secuencia de comandos PHP que se conectará a la base de datos MySQL que creó en el paso 1. La secuencia de comandos preparará tres productos de ejemplo y los insertará en la tabla products.

      Para crear el código PHP, abra un nuevo archivo con su editor de texto:

      • sudo nano /var/www/html/config.php

      Luego, ingrese la siguiente información en el archivo y reemplace PASSWORD por la contraseña test_user que creó en el paso 1:

      /var/www/html/config.php

      <?php
      
      define('DB_NAME', 'test_company');
      define('DB_USER', 'test_user');
      define('DB_PASSWORD', 'PASSWORD');
      define('DB_HOST', 'localhost');
      
      $pdo = new PDO("mysql:host=" . DB_HOST . "; dbname=" . DB_NAME, DB_USER, DB_PASSWORD);
      $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
      $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
      
      

      Guarde y cierre el archivo.

      En este archivo, utilizó cuatro constantes PHP para conectarse a la base de datos MySQL que creó en el paso 1:

      • DB_NAME : esta constante contiene el nombre de la base de datos test_company.

      • DB_USER : esta variable contiene el nombre de usuario test_user.

      • DB_PASSWORD : esta constante almacena la PASSWORD de MySQL de la cuenta test_user.

      • DB_HOST: esto representa el servidor en el que se ubica la base de datos. En este caso, utilizará el servidor localhost.

      Con la siguiente línea de su archivo se inicia un objeto de datos de PHP (PDO) y se conecta a la base de datos MySQL:

      ...
      $pdo = new PDO("mysql:host=" . DB_HOST . "; dbname=" . DB_NAME, DB_USER, DB_PASSWORD);
      ...
      

      Cerca del final del archivo, configuró algunos atributos PDO:

      • ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION: este atributo indica a PDO que inicie una excepción que se puede registrar para depuración.
      • ATTR_EMULATE_PREPARES, false: esta opción aumenta la seguridad al indicar al motor de la base de datos MySQL que realice la preparación en lugar de PDO.

      Incluirá el archivo /var/www/html/config.php en dos secuencias de comandos PHP que creará luego para insertar y recuperar registros respectivamente.

      Primero, cree la secuencia de comandos PHP /var/www/html/insert_products.php para insertar registros en la tabla de productos:

      • sudo nano /var/www/html/insert_products.php

      Luego, añada la siguiente información al archivo /var/www/html/insert_products.php:

      /var/www/html/insert_products.php

      <?php
      
      require_once 'config.php';
      
      $products = [];
      
      $products[] = [
                    'product_name' => 'VIRTUAL SERVERS',
                    'price' => 5,
                    'product_image' => file_get_contents("https://i.imgur.com/VEIKbp0.png")
                    ];
      
      $products[] = [
                    'product_name' => 'MANAGED KUBERNETES',
                    'price' => 30,
                    'product_image' => file_get_contents("https://i.imgur.com/cCc9Gw9.png")
                    ];
      
      $products[] = [
                    'product_name' => 'MySQL DATABASES',
                    'price' => 15,
                    'product_image' => file_get_contents("https://i.imgur.com/UYcHkKD.png" )
                    ];
      
      $sql = "INSERT INTO products(product_name, price, product_image) VALUES (:product_name, :price, :product_image)";
      
      foreach ($products as $product) {
          $stmt = $pdo->prepare($sql);
          $stmt->execute($product);
      }
      
      echo "Records inserted successfully";
      

      Guarde y cierre el archivo.

      En el archivo, incluyó el archivo config.php en la parte superior. Este es el primer archivo que creó para definir las variables de la base de datos y conectarse a la base de datos. El archivo también inicia un objeto PDO y lo almacena en una variable $pdo.

      Luego, creó una matriz de datos de los productos que se insertarán en la base de datos. Aparte de product_name y price, que se preparan como cadenas y valores numéricos respectivamente, la secuencia de comandos utiliza la función file_get_contents integrada de PHP para leer imágenes de una fuente externa y pasarlas como cadenas a la columna product_image.

      Luego, preparó una instrucción SQL y utilizó la instrucción foreach{...} de PHP para insertar cada producto en la base de datos.

      Para ejecutar el archivo /var/www/html/insert_products.php, realice la ejecución en la ventana de su navegador utilizando la siguiente URL. Recuerde reemplazar your-server-IP por la dirección IP pública de su servidor:

      http://your-server-IP/insert_products.php
      

      Después de ejecutar el archivo, verá un mensaje de éxito en su navegador confirmando que los registros se insertaron en la base de datos.

      Mensaje de éxito que indica que los registros se insertaron en la base de datos

      Insertó con éxito tres registros que contienen imágenes de productos en la tabla products. En el siguiente paso, creará una secuencia de comandos PHP para obtener estos registros y mostrarlos en su navegador.

      Paso 3: Mostrar la información de los productos de la base de datos MySQL

      Con la información e imágenes de los productos en la base de datos, ahora debe codificar otra secuencia de comandos PHP que consulta y muestra la información de los productos en una tabla HTML en su navegador.

      Para crear el archivo, escriba lo siguiente:

      • sudo nano /var/www/html/display_products.php

      Luego, ingrese la siguiente información en el archivo:

      /var/www/html/display_products.php

      <html>
        <title>Using BLOB and MySQL</title>
        <body>
      
        <?php
      
        require_once 'config.php';
      
        $sql = "SELECT * FROM products";
        $stmt = $pdo->prepare($sql);
        $stmt->execute();
        ?>
      
        <table border="1" align = 'center'> <caption>Products Database</caption>
          <tr>
            <th>Product Id</th>
            <th>Product Name</th>
            <th>Price</th>
            <th>Product Image</th>
          </tr>
      
        <?php
        while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
            echo '<tr>';
            echo '<td>' . $row['product_id'] . '</td>';
            echo '<td>' . $row['product_name'] . '</td>';
            echo '<td>' . $row['price'] . '</td>';
            echo '<td>' .
            '<img src = "data:image/png;base64,' . base64_encode($row['product_image']) . '" width = "50px" height = "50px"/>'
            . '</td>';
            echo '</tr>';
        }
        ?>
      
        </table>
        </body>
      </html>
      

      Guarde los cambios del archivo y ciérrelo.

      Aquí, nuevamente incluyó el archivo config.php para establecer conexión con la base de datos. Luego, preparó y ejecutó una instrucción SQL utilizando PDO para obtener todos los elementos de la tabla products utilizando el comando SELECT * FROM products​​​.

      Luego, creó una tabla HTML y la completó con los datos de los productos utilizando la instrucción PHP while() {...}​​​. La línea $row = $stmt->fetch(PDO::FETCH_ASSOC)​​​ consulta la base de datos y almacena el resultado en la variable $row como matriz multidimensional, que luego se mostró en una columna de la tabla HTML utilizando la sintaxis $row['column_name']​​​.

      Las imágenes de la columna product_image se incluyen en el interior de las etiquetas <img src = "">. Se utilizan los atributos width y height para cambiar el tamaño de las imágenes por uno más pequeño que pueda caber en la columna de la tabla HTML.

      Para convertir los datos contenidos en el tipo de datos BLOB de vuelta en imágenes, se utilizan la función base64_encode de PHP integrada y la siguiente sintaxis para el esquema URI de datos:

      data:media_type;base64, base_64_encoded_data
      

      En este caso, imagen/png es media_type y la cadena codificada Base64 de la columna product_image es base_64_encoded_data.

      Luego, ejecute el archivo display_products.php en un navegador web escribiendo la siguiente dirección:

      http://your-server-IP/display_products.php
      

      Después de ejecutar el archivo display_products.php en su navegador, verá una tabla HTML con una lista de productos e imágenes asociados.

      Lista de productos de la base de datos MySQL

      Esto confirma que la secuencia de comandos de PHP para obtener imágenes de MySQL funciona según lo previsto.

      Conclusión

      A través de esta guía, utilizó el tipo de datos BLOB de MySQL para almacenar y mostrar imágenes con PHP en Ubuntu 18.04. También vio las ventajas básicas de almacenar imágenes en una base de datos respecto de hacerlo en un sistema de archivos. Entre ellas, se incluyen la portabilidad, la seguridad y la facilidad de respaldo. Si compila una aplicación, como un portal de estudiantes o una base de datos de empleados para los cuales se deban almacenar juntas la información y las imágenes relacionadas, esta tecnología puede resultarle muy útil.

      Para obtener más información sobre los tipos de datos compatibles en MySQL, consulte la guía de tipos de datos de MySQL. Si está interesado en más contenido relacionado con MySQL y PHP, consulte los siguientes tutoriales:



      Source link