The filesystem

As you might have already noticed, PHP comes with a lot of native functions that help you to manage arrays and strings in an easier way as compared to other languages. The filesystem is another of those areas where PHP tried to make it as easy as possible. The list of functions extends to over 80 different ones, so we will cover here just the ones that you are more likely to use.

Reading files

In our code, we define a list of books. So far, we have only three books, but you can guess that if we want to make this application useful, the list will grow way more. Storing the information inside your code is not practical at all, so we have to start thinking about externalizing it.

If we think in terms of separating the code from the data, there is no need to keep using PHP arrays to define the books. Using a less language-restrictive system will allow people who do not know PHP to edit the content of the file. There are many solutions for this, like CSV or XML files, but nowadays, one of the most used systems to represent data in web applications is JSON. PHP allows you to convert arrays to JSON and vice versa using just a couple of functions: json_encode and json_decode. Easy, right?

Save the following into books.json:

[
    {
        "title": "To Kill A Mockingbird",
        "author": "Harper Lee",
        "available": true,
        "pages": 336,
        "isbn": 9780061120084
    },
    {
        "title": "1984",
        "author": "George Orwell",
        "available": true,
        "pages": 267,
        "isbn": 9780547249643
    },
    {
        "title": "One Hundred Years Of Solitude",
        "author": "Gabriel Garcia Marquez",
        "available": false,
        "pages": 457,
        "isbn": 9785267006323
    }
]

The preceding code snippet is a JSON representation of our array in PHP. Now, let's read this information with the function file_get_contents, and transform it to a PHP array with json_decode. Replace the array with these two lines:

$booksJson = file_get_contents('books.json');
$books = json_decode($booksJson, true);

With just one function, we are able to store all the content from the JSON file in a variable as a string. With the function, we transform this JSON string into an array. The second argument in json_decode tells PHP to transform it to an array, otherwise it would use objects, which we have not covered as yet.

When referencing files within PHP functions, you need to know whether to use absolute or relative paths. When using relative paths, PHP will try to find the file inside the same directory where the PHP script is. If not found, PHP will try to find it in other directories defined in the include_path directive, but that is something you would like to avoid. Instead, you could use absolute paths, which is a way to make sure the reference will not be misunderstood. Let's see two examples:

$booksJson = file_get_contents('/home/user/bookstore/books.json');
$booksJson = file_get_contents(__DIR__, '/books.json');

The constant __DIR__ contains the directory name of the current PHP file, and if we prefix it to the name of our file, we will have an absolute path. In fact, even though you might think that writing down the whole path by yourself is better, using __DIR__ allows you to move your application anywhere else without needing to change anything in the code, as its content will always match the directory of the script, whereas the hardcoded path from the first example will not be valid anymore.

Writing files

Let's add some functionality to our application. Imagine that we want to allow the user to take the book that he or she is looking for, but only if it is available. If you remember, we identify the book by the query string. That is not very practical, so let's help the user by adding links to the list of books, so when you click on a link, the query string will contain that book's information.

<?php require_once 'functions.php' ?>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Bookstore</title>
</head>
<body>
    <p><?php echo loginMessage(); ?></p>
<?php
$booksJson = file_get_contents('books.json');
$books = json_decode($booksJson, true);
if (isset($_GET['title'])) {
    echo '<p>Looking for <b>' . $_GET['title'] . '</b></p>';
} else {
    echo '<p>You are not looking for a book?</p>';
}
?>
    <ul>
<?php foreach ($books as $book): ?>
    <li>
        <a href="?title=<?php echo $book['title']; ?>">
            <?php echo printableTitle($book); ?>
        </a>
    </li>
<?php endforeach; ?>
    </ul>
</body>
</html>

If you try the preceding code in your browser, you will see that the list contains links, and by clicking on them, the page refreshes with the new title as part of the query string. Let's now check if the book is available or not, and if it is, let's update its available field to false. Add the following function in your functions.php:

function bookingBook(array &$books, string $title): bool {
    foreach ($books as $key => $book) {
        if ($book['title'] == $title) {
            if ($book['available']) {
                $books[$key]['available'] = false;
                return true;
            } else {
                return false;
            }
        }
    }
    return false;
}

We have to pay attention as the code starts getting complex. This function takes an array of books and a title, and returns a Boolean, being true if it could book it or false if not. Moreover, the array of books is passed by reference, which means that all changes to that array will affect the original array too. Even though we discouraged this previously, in this case, it is a reasonable approach.

We iterate the whole array of books, asking each time if the title of the current book matches the one we are looking for. Only if that is true, we will check if the book is available or not. If it is, we will update the availability to false and return true, meaning that we booked the book. If the book is not available, we will just return false.

Finally, note that foreach defines $key and $book. We do so because the $book variable is a copy of the $books array, and if we edit it, the original one will not be affected. Instead, we ask for the key of that book too, so when editing the array, we use $books[$key] instead of $book.

We can use this function from the index.php file:

//...
    echo '<p>Looking for <b>' . $_GET['title'] . '</b></p>';
    if (bookingBook($books, $_GET['title'])) {
        echo 'Booked!';
    } else {
        echo 'The book is not available...';
    }
} else {
//...

Try it out in your browser. By clicking on an available book, you will get the Booked! message. We are almost done! We are just missing the last part: persist this information back to the filesystem. In order to do that, we have to construct the new JSON content and then to write it back to the books.json file. Of course, let's do that only if the book was available.

function updateBooks(array $books) {
    $booksJson = json_encode($books);
    file_put_contents(__DIR__ . '/books.json', $booksJson);
}

The json_encode function does the opposite of json_decode: it takes an array—or any other variable—and transforms it to JSON. The file_put_contents function is used to write to the file referenced as the first argument, the content sent as the second argument. Would you know how to use this function?

//...
if (bookingBook($books, $_GET['title'])) {
    echo 'Booked!';
    updateBooks($books);
} else {
    echo 'The book is not available...';
}
//...

Note

Files versus databases

Storing information in JSON files is better than having it in your code, but it is still not the best option. In Chapter 5, Using Databases, you will learn how to store data of the application in a database, which is a way better solution.

Other filesystem functions

If you want to make your application more robust, you could check that the books.json file exists, that you have read and write permission, and/or that the previous content was a valid JSON. You can use some PHP functions for that:

  • file_exists: This function takes the path of the file, and returns a Boolean: true when the file exists and false otherwise.
  • is_writable: This function works the same as file_exists, but checks whether the file is writable or not.

You can find the full list of functions at http://uk1.php.net/manual/en/book.filesystem.php. You can find functions to move, copy, or remove files, create directories, give permissions and ownership, and so on.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.97.187