Q:

How to securely implement the "Remember me" button in PHP (persistent login)

First some background, I'm still learning PHP and I'm trying to build a CMS (disclaimer: for my own use only).
I'm still testing some things and I've succesfully created an admin login system.
So, right now this is how it works:

User logs in, after validating and sanitizing inputs, I check if the user exists and I use PHPs password_verify to compare the password to the hashed one stored in the DB.
If the login in is successful, I redirect the admin to a dashboard.php and create a session variable called adminId and I store the user ID in that variable.

Here's my first question:
Can an attacker change the value of the $_SESSION['adminId']? For example, change from 1, to 12 and, therefore, login in as a different admin?
Anyway, I've read this article that introduces multiple exploits an attacker can use.
So, if I'm not wrong, I should use cookies for persistent login right?
Ok so the first thing is to never store the user id in a cookie and use that to check for the log in because an attacker can easily change that right?
Fine, so I could create a random token (with random_bytes and then converted to hex) and pair it to a user ID in a logins table in the database. 
So for example, I have this:
token: 2413e99262bfa13d5bf349b7f4c665ae2e79e357,
userId: 2

So, the user logs in, token is created, stored in database with userId.
Suppose the user closes the browser.
Then he opens it again and all it has is the cookie with the token: 2413e99262bfa13d5bf349b7f4c665ae2e79e357. So automatically, it logs in the user with userId: 2 right?
If he wanted to log in as the user with userId: 10 for example, he would need to know the random token paired to that user.
Fine, but then there's this problem: timing leaks. So they propose a solution using two things, a selector and a validator. Here's when I don't understand anymore, this is what the article says:

What follows is our proposed strategy for handling "remember me" cookies in a web application without leaking any useful information (even timing information) to an attacker, while still being fast and efficient (to prevent denial of service attacks).
Our proposed strategy deviates from the above simple token-based automatic login system in one crucial way: Instead of only storing a random token in a cookie, we store selector:validator.
selector is a unique ID to facilitate database look-ups, while preventing the unavoidable timing information from impacting security. (This is preferable to simply using the database id field, which leaks the number of active users on the application.)

On the database side of things, the validator is not stored wholesale; instead, the SHA-256 hash of validator is stored in the database, while the plaintext is stored (with the selector) in the user's cookie. With this fail-safe in place, if somehow the auth_tokens table is leaked, immediate widespread user impersonation is prevented.
The automatic login algorithm looks something like:

Separate selector from validator.
Grab the row in auth_tokens for the given selector. If none is found, abort.
Hash the validator provided by the user's cookie with SHA-256.
Compare the SHA-256 hash we generated with the hash stored in the database, using hash_equals().
If step 4 passes, associate the current session with the appropriate user ID.

So here's what I don't understand:
1) What should the selector and validator contain?
2) Why is this system secure and how it prevents timing leaks?
Thanks in advance, and sorry for long post, but I really want to understand how this works and how can I implement it.
I know I could use some framework or library but I want to make it from scracth, learn by trial and error!

A:

Can an attacker change the value of the $_SESSION['adminId']? For example, change from 1, to 12 and, therefore, login in as a different admin?

No.  The session data is stored only on the server.  The client only has the string which identifies the session.

I should use cookies for persistent login right?

If you're going to have persistent logins, this is usually how it's done.

so the first thing is to never store the user id in a cookie and use that to check for the log in because an attacker can easily change that right?

Correct, you will never want to expose any critical data such as a user id.

1) What should the selector and validator contain?

Each would be a properly generated random string (e.g. using openssl_random_pseudo_bytes).  The selector must be unique.

2) Why is this system secure and how it prevents timing leaks?

It adds two security features over generating one basic token and looking that up directly.  
First, if your database is leaked to an attacker they can not generate their own remember me cookies and impersonate every user.  The validator is only stored in the database as a hashed value.  The cookie must contain the unhashed value.  Reversing a good hash is extremely time consuming.
Second, comparing a hash only generated on the server avoids timing attacks.  If an attacker were to send various remember me cookie values to time their lookup, it wouldn't expose anything useful because the comparison on the server is against a hashed value and not the original.
Generally speaking, if your system's security is that important I would recommend against supporting a remember me feature at all.  If you do want to use this feature on a important site, use a library which has already been tested to be secure.

