Blog

PHP Arhitect January 2022

Cybersecurity

Introducing FilterIterators

Mauro Chojrin

Iterators over collections provide a clean separation of concerns. Filter Iterators are a great way to abstract the logic of your selecting sub-sets of Collections elements.

Introduction

This article will provide an overview of what Collections are and why you should prefer them to plain PHP arrays. Then I’ll focus on one particular aspect of working with Collections: filtering elements. You’ll have the opportunity to see an implementation of the concepts discussed in the context of a coding challenge issued as part of an actual technical interview. By reading this article, you’ll learn how to structure your code to better prepare for eventual requirement changes.

Setting the Ground

Before jumping into the details, it makes sense to take a moment to explore some basic concepts, namely Collections and Iterators.

What is a Collection?

A Collection is basically a set of objects stored together in memory. The simplest form of a Collection is an Array or a LinkedList. These are simple in the sense that elements are stored in a linear sequence, thus making the iteration over them trivial: when you’re processing an element there’s no doubt about which one comes next. Usually, PHP arrays will do the job, no argument about that, but if you want to make your code easily reflect your ideas, relying on specialized structures will be extremely useful. This article will show you my own Collection implementation for simplicity. Alternatively, since version 7, PHP offers a nice implementation through its DS extension[1]. I recommend you check it out if you’re not familiar with it yet.

What is an Iterator?

An Iterator is an Object whose sole responsibility is to loop through the elements contained within a Collection using a particular algorithm. An Iterator should not modify the underlying Collection but act on it as a mere observer. In the case of PHP, Iterators are implemented as part of the SPL extension[2], which I’ll be using in the code examples below.

What is the Need for Iterators?

We use Iterators is to separate the storage from the iteration over the elements. In a way, it’s an attempt to respect the Single Responsibility Principle (The S in SOLID[3]) .

1 DS extension: https://www.php.net/book.ds

2 SPL extension: https://www.php.net/spl.iterators

3 SOLID: https://www.thinktocode.com/?p=47

Think of a complex Collection, such as a tree or a graph. In this kind of structure, there are many ways to loop through the elements. You could have, for instance, a method that would return the next element of the Collection in a breadth-firstsearch, then another in a depth-first-search. And then, later, perhaps you’ll need to iterate over the elements in ascending numerical order and, since you’re at it, why not implement another one that will traverse the set by creation order. If you follow this path, you’ll soon find yourself changing the Collection class on a regular basis. Definitely not a good idea if you want to keep the bug count low. That’s what Iterators come to solve: they provide a clean way to create new looping mechanisms without changing the code that deals with memory organization and such. When a new iteration criteria is needed all you have to do is put together a new Iterator class and the rest of your application can stay untouched. If you want to go deeper into these concepts I recommend reading this great article on Iterators[4].

Different Kinds of Iterators

There are many kinds of Iterators[5] that can be created for a given Collection. Let’s take a quick look at some of them:

  • AppendIterator[6]. This class allows the combination of Iterators in a sequential style (When one Iterator reaches the end of the underlying collection, the loop continues over the next one until all of them have been consumed).

  • InfiniteIterator[7]. This class is used to produce a circular iteration: when the end of the loop is reached, the Iterator is automatically rewound, so there’s always a next element.

  • LimitIterator[8]. This class is used to loop over a fixed sub-set of the Collection’s elements. All of these are examples of Iterators that can be composed with others, allowing for the construction of complex iteration logic. Specific Iterators are designed to work exclusively

4 Iterators: https://phpa.me/refactoring-guru-iterator

5 many kinds of Iterators: https://www.php.net/spl.iterators

6 AppendIterator: https://www.php.net/class.appenditerator

7 InfiniteIterator: https://www.php.net/class.infiniteiterator

8 LimitIterator: https://www.php.net/class.limititerator


with the file system, such as the DirectoryIterator[9] and its family. Apart from these, you can create your own if you find the need to put together a more specific iteration algorithm.

Filteriterators

One particularly interesting type of Iterator is the FilterIterator[10]. This class is designed to loop through a subset of the elements of a Collection. Yet, unlike the LimitIterator, the subset is not fixed but dynamic. LimitIterator elements are selected via applying a filtering function to each one and retaining those for which the result is true. A FilterIterator won’t work directly on the collection. Instead, it leverages a pre-existing Iterator to access the elements and is another composite Iterator. Going back to our graph example, say you have a breadth-first-search Iterator implemented, and now you want to process a particular set of those nodes. A nice way to accomplish that would be to design a FilterIterator and then use it together with the graph.

A Somewhat Real Use Case

Recently I got this email from a programmer I’ve been coaching:

Hi Mauro,

It’s been a while, hope you are doing great?

I have a PHP coding challenge that needs to be solved using solid prin- ciples, and also I think it involves using the PHP Iterator class, which I’m not familiar with. Can you help me out with it?

I hope you can help me out. I really need to understand the best way to solve this.

9 DirectoryIterator: https://www.php.net/class.directoryiterator

10 FilterIterator:

https://www.php.net/class.filteriterator

The problem to be solved was expressed like this:

Your task is to create a CLI script that will read JSON-based data from a specific endpoint via HTTP. The script will contain several sub-commands to filter and output the loaded data. The commands should be:

Find objects by price range (given price_from and price_to as argu- ments). Find objects by a certain sub-object definition. All given sub-commands should only output the number of objects in stock.

Technical Requirements:

Implement the ReaderInterface for fetching the JSON HTTP endpoint and thus work with the OfferCollec- tionInterface and OfferInterface on the loaded data.

Listing 1 shows a little script[11] I put together to solve the problem and help my student understand the underlying concepts.

11 a little script:

https://github.com/mchojrin/HTTPJsonFilter

Listing 1.

 1. <?php
 2.
 3. spl_autoload_register(function (string $className) {
 4. require_once $className . '.php';
 5. });
 6.
 7. $httpReader = new HTTPReader();
 8. $jsonData = file_get_contents($_ENV['OFFERS_ENDPOINT']);
 9.
10. $offerCollection = $httpReader->read($jsonData);
11.
12. $subcommand = $argv[1];
13.
14. $productIterator = $offerCollection->getIterator();
15. $subcommand2FilterMapping = [
16. 'count_by_price_range' => function (Iterator $productIterator, array $argv) {
17. return new PriceFilterIterator($productIterator, $argv[2], $argv[3]);
18.   },
19. 'count_by_vendor_id' => function(Iterator $productIterator, array $argv) {
20. return new VendorIdFilterIterator($productIterator, intval($argv[2]));
21.   },
22. ];
23.
24. // Please note that validation is left out to simplify the example.
25.
26. echo iterator_count($subcommand2FilterMapping[$argv[1]]($productIterator, $argv));

I’ll go over its main parts to show how the FilterIterator can be implemented in PHP. Let’s start with the main script, the file run.php shown in Listing 1. Here you can see how the script:

  1. Incorporates a very simple autoloading function by calling
   spl_autoload_register. Doing

so is meant to prevent the explicit requirement of supporting classes over the rest of the code. 2. Creates a Product Collection through an HTTPReader instance. The HTTPReader’s goal is to create a new Collection from the results of applying json_

   decode to the text gathered from

the external endpoint. 3. Outputs the number of elements in the Collection that match the criteria specified by a command-line argument by calling the function iterator_ count[12] and feeding it with the appropriate Iterator.

12 iterator_count:

https://www.php.net/function.iterator-count


The last point is where I want you to focus your attention. Note how, depending on the specified sub-command, a particular FilterIterator sub-class is used on top of the original Iterator. Listing 2 shows the code for PriceFilterIterator. This class has two methods:

  • The constructor

  • accept

 accept is the most important part of the class, as it’s where

the actual filtering logic is stored. In this particular case, the way to determine whether a product should be part of the iteration is checking that its price is within established boundaries. These boundaries are defined when creating the Iterator’s instance. They are the arguments to the constructor method. Every FilterIterator works this way: the accept method is called upon each element yielded by the underlying Iterator and, if the evaluation results in a boolean true, the element will be considered part of the loop; otherwise, it will be skipped. Now look at the VendorIdFilterIterator class shown in Listing 3. The structure is pretty much the same. The only significant difference is the definition of the accept method, which, in this case, checks the vendor Id against a fixed value established at construction time. Since this is just a simulation, this Proof Of Concept project includes a script named output_json.php (Listing 4) that will produce the JSON output expected at the other end. To test this code — first, spin up a server that can act as a remote endpoint. A simple way to do that is by running

php -S localhost:8000 output_json.php.

Then, if you issue the command

Listing 3.

 1. <?php
 2.
 3. class VendorIdFilterIterator extends FilterIterator
 4. {
 5. private int $vendorId;
 6.
 7. public function __construct
 8. (Iterator $iterator, int $vendorId)
 9.   {
10. parent::__construct($iterator);
11. $this->vendorId = $vendorId;
12.   }
13.
14. public function accept() : bool
15.   {
16. $vendor_id = current()->getVendorId();
17. return $vendor_id === $this->vendorId;
18.   }
19. }

OFFERS_ENDPOINT=http://localhost:8000 php run.php count_
by_price_range 200 500

you’ll get 2 as a response and, if you use the following, you’ll get 1.

OFFERS_ENDPOINT=http://localhost:8000 php run.php count_
by_vendor_id 84

Listing 4.

 1. <?php
 2.
 3. header('Content-Type: application/json');
 4.
 5. echo json_encode([
 6.   [
 7. 'offerId' => 123,
 8. 'productTitle' => 'Coffee machine',
 9. 'vendorId' => 35,
10. 'price' => 390.4,
11.   ],
12.   [
13. 'offerId' => 124,
14. 'productTitle' => 'Napkins',
15. 'vendorId' => 35,
16. 'price' => 15.5,
17.   ],
18.   [
19. 'offerId' => 125,
20. 'productTitle' => 'Chair',
21. 'vendorId' => 84,
22. 'price' => 230.0,
23.   ],
24. ]);


Listing 5.

 1. <?php
 2.
 3. class ProductTitlePrefixFilterIterator extends FilterIterator
 4. {
 5. private string $prefix;
 6.
 7. public function __construct(Iterator $iterator, string $prefix)
 8.   {
 9. parent::__construct($iterator);
10. $this->prefix = $prefix;
11.   }
12.
13. public function accept() : bool
14.   {
15. return str_starts_with(
16. parent::current()->getProductTitle(),
17. $this->prefix);
18.   }
19. }

Listing 6.

 1. $subcommand2FilterMapping = [
 2. 'count_by_price_range' => function (Iterator $productIterator, array $argv) {
 3. return new PriceFilterIterator($productIterator, $argv[2], $argv[3]);
 4.   },
 5. 'count_by_vendor_id' => function (Iterator $productIterator, array $argv) {
 6. return new VendorIdFilterIterator($productIterator, intval($argv[2]));
 7.   },
8. 'count_by_title_prefix' => function (Iterator $productIterator, array $argv) {
 9. return new ProductTitlePrefixFilterIterator($productIterator, $argv[2]);
10.   },
11. ];

To filter results by any other criteria, such as Product Title, you would have to:

  1. Create a new FilterIterator class
  2. Add a new entry to $subcommand``` 2FilterMapping
The first point will end with you
having a class such as Listing 5.
And a mapping defined like Listing 6.
Finally, to test it, run `OFFERS_`

ENDPOINT=http://localhost:8000 php

run.php count_by_title_prefix Ch and
you should get 1 as a result.
Of course, the use of these filters is by
no means limited to counting elements.
Once the sub-set is computed, you can
do whatever you need with them. In
fact, you can use these filters as a basis
for the application of others if that
makes sense for the problem you’re
looking to solve.
Another approach to getting these
results would be to rely on array
filtering functions instead of FilterIterators, like Listing 7.
The main “problem” with this is
that it doesn’t comply with the specific
requirement of the challenge, so it
doesn’t really constitute a valid answer
for the case under analysis.


Listing 7.
  1. spl_autoload_register(function (string $className) {
  2. require_once $className . ‘.php’;
  3. });
  4. $httpReader = new HTTPReader();
  5. $jsonData = file_get_contents($_ENV[‘OFFERS_ENDPOINT’]);
  6. $offerCollection = $httpReader->read($jsonData);
  7. $subcommand = $argv[1];
  8. $subcommand2FilterMapping = [
  9. ‘count_by_price_range’ => function (OfferCollection $collection, array $argv) {
  10. return count(array_filter($collection->toArray(), function (Offer $offer) use ($argv) {
  11. return $offer->getPrice() >= $argv[2] && $offer->getPrice() <= $argv[3];
  12. }));
    
  13. },
  14. ];
  15. echo $subcommand2FilterMapping[$argv[1]]($offerCollection, $argv);

-----

In a more realistic scenario, this could be a way to get the
answers you’re looking for. You can see how it is even a less
verbose implementation, which could be preferred in some
situations.
I have two main concerns about this:

1. The code is not as well organized as the former.
2. It requires the introduction of an ad hoc `toArray`
method to match the array_filter function signature,
which makes using a Collection pointless.

The fact that the array_filter function forces the first argument to be an array instead of something that can be iterated
over is, in my opinion, a language shortcoming. Who knows,
perhaps this will be changed in the future, but for the time
being, this is the reality.
A third way to tackle this issue would be to provide a way
for the Collection to filter itself. That could be interesting,
especially if this filtering method got a callback as an argument, thus giving it a lot of flexibility:

public function filter(Callable $filter) { return new OfferCollection( array_filter( $this->offers, $filter ) ); }


I’d still be a bit skeptical about such an implementation in
terms of how that would play out in the long run, though. It
seems like we might be putting a little too much responsibility
in the Collection class.

###### Conclusion

In this article, you learned about Collections, Iterators in
general, and FilterIterators in particular.
While the usage of Collections and, in general, advanced
data structures is not a very common practice when it comes
to PHP, many new and interesting tools are available to use
to your advantage, especially if you’re up-to-date with your
PHP version.
I hope I was able to poke your curiosity and show you a bit
of how you can structure your code to make it easier to read
and maintain over time.

_Mauro Chojrin is a PHP Trainer and_
_Consultant. He has been involved in the_
_IT Industry since 1997 in a wide array of_
_positions, including technical support, devel-_
_opment, team leadership, IT management,_
_and teaching. He also maintains his blog[13]_
_and YouTube channel[14] where he shares his_
_knowledge with the world._

_[13 his blog: https://academy.leewayweb.com](https://academy.leewayweb.com)_
_[14 YouTube channel: https://phpa.me/youtube-leeway](https://phpa.me/youtube-leeway)_


-----

-----

#### How to Hack your Home with a Raspberry Pi - Part 1 - Installing the OS and Configuring the Pi

###### Ken Marks

 In September of 2017, I gave a talk called: ‘Hack your Home with a Raspberry Pi’ at the Madison PHP Conference. It was a half-day tutorial, walking participants through the process of configuring a Raspberry Pi, installing a LAMP stack on it, connecting a sensor, and ultimately having it send a text message to their phone.


Since then, I have been running this
as a lab for my Advanced PHP class I
teach at our local community college,
Madison College.
One of the main reasons I gave this
tutorial was to dispel the myth of the
Internet of Things (IoT) being difficult. Sometimes people get scared
away from writing code that talks to
small embedded devices (i.e., sensors
connected to Raspberry Pis or Arduino
boards). My goal is to show you how
easy it is to create a device that reports
sensor data that you can get on a
network. Along the way, you will see
that deploying an application to a Raspberry Pi is just as simple as deploying to
any Linux-based LAMP stack! [should I
say, it’s as easy as Pi :-)]
This article is the first of several in
a series. I know php[architect] Magazine is a publication dedicated to PHP
development, but I hope it doesn’t scare
you that not all the code you will be
deploying/using in this series will be
PHP 😱. In addition to PHP (and SQL),


we will be using C/C++ and JavaScript.
We will be creating a couple of UNIX
services as well. So come along on this
journey with me as I show you how to
hack your home with a Raspberry Pi!
The goals for the whole series (can we
call it a project?) are:

 - Installing the Raspberry Pi operating system

 - Configuring your Pi

 - Installing a LAMP Stack on your
Pi

 - Connecting an accelerometer
sensor to your Pi

 - Logging data from an accelerometer to a database

 - Creating and installing a Unix
Service on your Pi

 - Building a Web Service for querying the accelerometer data

 - Building a plotting application to
display the accelerometer data

 - Sending a text message to your
phone using SendMail


Wow! That’s a pretty big list which is
why it will take several articles to cover.
In this article, I will cover:

 - Installing the Raspberry Pi operating system

 - Configuring your Pi

###### It starts with a story…

My initial idea and motivation for
this series (project?) starts with a story
about our old clothes dryer, which quit
working one day. I was tasked with
replacing it. Everything was great, and
I got kudos for getting a decent dryer.
However, there was one annoying flaw
with this new dryer. We do our laundry
in the basement, and this new dryer
chimes at us — very quietly — when
the clothes are done. Our old dryer
buzzed its bloody head off when the
dry cycle was complete, and I swear you
could hear it from the street. Of course,
being the forward-thinking Rube Goldberg kind of person I am, I said, “I can
create an App for that!” So, since I was


New Samsung Dryer with Pi


-----

Raspberry Pi Form Factors


Head Soldered


If you use a Raspberry Pi Zero W, keep in mind that it only
supports 2.4GHz wireless. So, if your wireless router only
supports 5GHz, you might want to use another model of
the Pi. The Pi 3 B+ and 4 B support 2.4 and 5GHz wireless
ethernet. The upside of using the Pi 3 B+ or 4 B is that you
won’t have to do any soldering.

###### Do I really need to learn how to solder?

_What did the soldering iron say to the capacitor? Go flux_
_yourself!_

All Raspberry Pis have a General Purpose Input Output

Raspberry Pi 40pin header

(GPIO) bus which is a duel-row male 40 pin header used to
connect sensors and other devices to the Pi:
Later on, we’ll be connecting an accelerometer sensor to
the GPIO bus of the Pi. Because I’m using the Pi Zero W, I’ll
have to solder on a duel-row male 40 pin header onto the
board to expose the GPIO bus pins since the Pi Zero W board
does not come with it pre-populated.
I've included a few photos of me soldering the header onto
the Pi and 6 pins onto one version of the accelerometer sensor.


Pi Zero W in Case


Soldering Pins


Again, you can use any Raspberry Pi, but I thought it would
be really cool to use a Raspberry Pi half the size of a credit
card. I recommend you use a Raspberry Pi with wireless
ethernet built-in since that will be the configuration I will
document here.
Okay, let’s start a numbered list of the five items we will
need:
1. **Your computer**
You will need to have a computer connected to the
internet to download the Raspberry Pi Operating System.
Ideally, you will want to connect to your Pi via SSH from your
computer. I’m going to assume you are running some flavor
of Unix (Ubuntu, MacOS, etc.). However, there is plenty of
information on the internet for communicating with your
Raspberry Pi if you have a Windows PC.
2. **Your home wireless router**
I’m not going to go into how you configure this,
as everyone is different. I will assume you have one and go
through a generic method for connecting to it.
3. **Raspberry Pi**
I recommend getting a kit that includes a case, a
power supply, and an SD card. I get mine from CanaKit[1], but
you can get one from Amazon or any other Raspberry Pi
reseller).

_1_ _[CanaKit: https://www.canakit.com](https://www.canakit.com)_


Soldering Pins on
Accelerometer


-----

Here is a list of things associated with your Pi you might want to have

   - duel row 40 pin header (if you
buy a Pi Zero W). You can get this
from Amazon[2].

   - soldering iron and solder (if
you buy a Pi Zero W)

   - case

   - power supply for Pi

   - SD card at least 8GB. (It’s probably not worth getting one less than
16GB. I would recommend getting a
card rated at UHS-1 or better. Most
are).

   - SD card reader. Many Raspberry Pi kits come with one that plugs
into the USB port of your computer.

   - HDMI cable (if you want to
configure your Pi with a keyboard
and monitor)

   - keyboard (if you want to
configure your Pi with a keyboard
and monitor)

   - monitor (if you want to
configure your Pi with a keyboard
and monitor)
4. **Accelerometer**
There are a lot of different
accelerometer sensors available. I wanted one that uses the I2C bus for this
project — more on that later. There is
a small C program we will be using that
communicates with an _MMA8452Q_
triple-axis accelerometer. There are two
slightly different board types:

_2_ _Amazon:_
_[https://phpa.me/amazon-40pin-duel](https://phpa.me/amazon-40pin-duel)_


40 Pin Ribbon Cable


Duel row 40 pin Male Header



   - The MMA8452 shown in
Figure 1 can be purchased from
Sparkfun[3].

   - And the Keyes MMA8452Q,
which can be purchased from eBay[4].
See Figure 2.
The nice thing about the Keyes
version is that it comes pre-populated
with the 6 pins already soldered in
5. **female to female 4 pin ribbon**
**cable to connect the accelerometer to**
**Pi**

These typically come as a 40
pin ribbon cable, and you peel off 4
wires to connect the accelerometer
to the GPIO bus of the Pi. You can
purchase this from Amazon[5].

_3_ _Sparkfun:_
_[https://www.sparkfun.com/products/13926](https://www.sparkfun.com/products/13926)_
_4_ _[eBay: https://phpa.me/ebay-accelerometer](https://phpa.me/ebay-accelerometer)_

_5_ _Amazon:_
_[https://phpa.me/amazon-fem-jumper-40](https://phpa.me/amazon-fem-jumper-40)_


Figure 1. MMA8452 from Sparkfun


Now that we have all of our essential equipment and components, we
need to install an operating system and
configure our Raspberry Pi.

###### Downloading the Raspberry Pi OS image

First, we need to get an image of
the Raspberry Pi Operating System
(OS) and get it onto our SD card. The
best way to do that is to download the
_Raspberry Pi Imager[6]. There are links_
to download the imager for MacOS,
Windows, or Ubuntu on the page. You
can even use the apt package manager
within a UNIX terminal window to
install the _Raspberry Pi Imager. After_
downloading the Imager package for
your OS, follow the installation instructions.
Plug your SD card reader into your
computer and insert the SD card you
will be using for your Raspberry Pi.

_6_ _Raspberry Pi Imager:_
_[https://www.raspberrypi.com/software/](https://www.raspberrypi.com/software/)_


Figure 2. Keyes MMA8452Q from
eBay


-----

Launch the Raspberry Pi Imager, and you should see the
main screen of the Raspberry Pi Imager:

Main Screen of Raspberry Pi Imager

Select CHOOSE STORAGE, and a Storage dialog should be
displayed:


Select _Raspberry Pi OS (other), and the_ _Operating System_
dialog will display a list of Raspberry Pi operating systems to
choose from:

Pi Imager OS Dialog: Choose Raspberry Pi OS Lite (32-bit)

Select Raspberry Pi OS Lite (32-bit) - a Linux server installation that will minimize the amount of CPU utilization since
we’re not doing a full desktop installation. You will now be
returned to the main screen of the Raspberry Pi Imager:

Main Screen of Raspberry Pi Imager: WRITE

Now select WRITE to write the image to the SD card. You
will now see a Warning dialog, letting you know all existing
data on your SD card will be erased and ensure you want to
continue. Select YES.
You will usually see a Permissions dialog pop up asking you
to enter your admin password for your computer before you
can write to your SD card.
After entering your credentials, the Raspberry Pi Imager
will start writing the OS to your SD card. When the write
operation is complete, a _Write Successful dialog should be_
displayed. Select _CONTINUE, and quit the_ _Raspberry Pi_
_Imager application. You can now remove your SD card from_
your SD card reader.
Now we need to configure our Raspberry Pi. There are two
ways you can do this:

 - Headless configuration

 - Direct configuration


Pi Imager OS Dialog: Choose Raspberry Pi OS (other)


main screen of the Raspberry Pi Imager:

Main Screen of Raspberry Pi Imager


Raspberry Pi Imager Storage Dialog


-----

###### The book also walks you through building a typical Create-Read- Update-Delete (CRUD) application. Along the way, you’ll get solid, practical advice on how to add authentication, handle file uploads, safely store passwords, application security, and more.

 Available in Print+Digital and Digital Editions.


###### Learn how to build dynamic and secure websites.

 The book also walks you through building a typical Create-Read- Update-Delete (CRUD) application. Along the way, you’ll get solid, practical advice on how to add authentication, handle file uploads, safely store passwords, application security, and more.


#### Purchase Your Copy
###### https://phpa.me/php-development-book


-----

I will first show you the headless configuration as I find it’s
the simplest. Then I will show you the direct configuration.

###### Headless configuration

So, let’s say you have your Raspberry Pi, and you don’t
have a keyboard or extra monitor laying about, or like me,
you forgot all of that (and the magic HDMI dongle that came
with your Raspberry Pi Zero W kit)! Your only option at this
point is to perform a headless configuration on your Pi. That’s
a good thing because it’s usually the easiest option.
To create a headless configuration, we need to modify the
contents of the SD card so that when the Raspberry Pi boots,
it will:

 - Allow us to SSH into the Raspberry Pi

 - Connect the Pi to our Wi-Fi router
Re-insert your SD card back into your SD card reader.
Open up a terminal window and navigate to the root folder
of your SD card. I’m on a Mac and will go to /Volumes/boot:
To enable SSH, we need to create an empty file called ssh in
the boot folder of the SD card. Type the following command
in the terminal window:

touch /Volumes/boot/ssh

Next, we need to add our Wi-Fi network information. For
that, we need to create a file called wpa_supplicant.conf and
put it in the `boot folder of the SD card. Type the following`
command in the terminal window to create the `wpa_suppli-`

cant.conf file: touch /Volumes/boot/wpa_supplicant.conf

Next, we need to edit the wpa_supplicant.conf file and add

country=US ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev update_config=1 network={ ssid=“NETWORK-NAME” psk=“NETWORK-PASSWORD” }


require dongles to connect a standard HDMI cable and USB
keyboard. The Pi Zero even comes with a USB dongle.
Insert the SD card into your Raspberry Pi
Connect your Pi to a monitor and a keyboard.
Connect your power supply to your Pi and plug the power
supply into a mains A/C wall socket.
After the Raspberry Pi boots up, log in with the user pi and
the default password of raspberry.
Next, we need to add our Wi-Fi network information. For
that, we need to create a file called wpa_supplicant.conf and
put it into the /etc/wpa_supplicant/ folder. We will be using
the built-in nano editor to create the wpa_supplicant.conf file.
Since this file requires root access, we have to create this file
as superuser. Type the following command in the commandline terminal:

sudo nano /etc/wpa_supplicant/wpa_supplicant.conf

Now let’s edit the `wpa_supplicant.conf file and add our`
Wi-Fi network SSID and password. Paste the following into

country=US ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev update_config=1 network={ ssid=“NETWORK-NAME” psk=“NETWORK-PASSWORD” }


the editor, and update the country code as needed, and your
network SSID and password:
Type ^O to write out the file and ^X to exit the nano editor.
Next, we’re going to run the raspi-config tool so that your Pi
will allow SSH connections. Run the following command as
_superuser to display the main screen of the raspi-config tool._

sudo raspi-config


our Wi-Fi network SSID and password. Paste the following
into the editor, and update the country code as needed, and
your network SSID and password:
Save the file and exit your editor.
Eject the SD card and insert it into the Raspberry Pi
Mitch Allen has a complete set of instructions[7] for how to
create a headless configuration for your Raspberry Pi that
covers all the major operating systems of your host computer.

###### Direct configuration

Direct configuration requires connecting a USB keyboard
and HDMI monitor up to your Pi. Some Raspberry Pis

_7_ _[complete set of instructions: https://phpa.me/desertbot-pi-wifi-setup](https://phpa.me/desertbot-pi-wifi-setup)_


Main Screen: Select Interface Options


-----

Using the arrow keys, highlight 3 Interface Options and
press Enter, and the Interface Options screen will be displayed:

Interface Options: Select SSH

Using the _arrow keys, highlight_ `I2 SSH and press` `Enter,`
and a dialog asking, “Would you like the SSH server to be
enabled?” will pop up. Select Yes and press Enter.
Press `Enter after the dialog, “The SSH server is enabled”`
pops up, and you will be returned to the main screen of the
raspi-config tool. Using the tab key, select <Finish> and press

Enter.

Type the following into the command-line terminal to shut
down the Raspberry Pi:

sudo shutdown -h now

SSH into your Pi
Now connect the power supply to your Raspberry Pi and
plug it into A/C mains.
After a few minutes, type the following into a terminal to
remove any previous SSH keys generated for the host `rasp-`

berrypi.local: ssh-keygen -R raspberrypi.local

If you receive a host not found error, that’s okay. That just
means you didn’t have any previous SSH keys generated for

raspberrypi.local.

Next, SSH into your Pi with the user `pi by typing the`
following command into the terminal:

ssh pi@raspberrypi.local

Type in the default password of raspberry. If all goes well,
you should be logged in to your Raspberry Pi.

###### Run raspi-config

At this point, you want to configure your Raspberry Pi for
your locale settings, along with changing the password. To do
this, we will run the raspi-config program as superuser.
Assuming you are logged into your Pi using SSH, type the
following command into the terminal:

sudo raspi-config

You should see the raspi-config main screen displayed again.


We first need to make sure we have the latest version of the
raspi-config tool. Use the arrow keys to highlight 8 Update and
tab over to the <Select> option and press Enter.

raspi-config will be updated to the latest version, and the
_raspi-config main screen will be redisplayed with the System_
_Options highlighted. Tab over to the_ `<Select> option and`
press `Enter. The following System Options will be displayed,`
allowing you to change your password:

System Options: Select Password

Use the arrow keys to highlight S3 Password and tab over to
the <Select> option and press Enter. Follow the instructions
to enter your new password. For purposes of this series, I’ll
set mine to pizerow.
After changing your password, you will be taken back to the
main screen of the raspi-config tool. Next, we need to modify
the Interface Options to allow our Pi to use the GPIO bus and
talk to our accelerometer sensor we will be connecting to it
later on. Use the arrow keys to highlight 3 Interface Options
and tab over to the <Select> option and press Enter.
We specifically want to enable the _I2C bus, as that is the_
protocol our accelerometer will use to communicate with the
Pi. Use the arrow keys to highlight I5 I2C and tab over to the