PHP 0 to hero pt.7 - Strings
Tags: programming, beginners, php, tutorial
Published: 2024-01-04 15:00:00


Hi
The new year has come
But now, let's focus on coding- today strings

Plenty of data consists of text - that's why we have **strings**
Their presence allows us to modify and just do whatever the hell we want to with text data

That's it for the intro - let's see what we will learn today

1. How to define strings
2. Comparing strings
3. Obtaining first/last letter of a string
4. Joining strings
5. Validating strings (like e-mail)
6. Passwords and hashing

So, let's start coding

## Defining

To define a string, we do exactly the same thing as always - add `$` to the beginning of the name, and assign some value

```php
$myString = "Wow, I am a string";
```

And now, should we define it with `""` or with `'`?  However we want

Does it matter? Yes, it does.

If we define/output a string with double-quotes - we can put a variable inside and it will output it's contents 

ex.
```php
$var = "Hello";
echo "$var World";
// Hello World 
```
But if we try to display it with single-quotes (`'`) - it will look like this

```php
$var = "Hello";
echo '$var World';
// $var World 
```

You see? Even though we declared `$var`, it didn't inject it's contents inside `echo` statement 

## Comparing
With comparing, we have 2 options

1. `==` operator
2. Using `strcmp()` function

And there is a catch, while `==` returns us boolean value:

```php
$str1 = "hello";
$str2 = "hello";

var_dump($str1 == $str2);
// bool(true)
```

`strcmp()` gives us integer 
```php
$str1 = "hello";
$str2 = "hello";

var_dump(strcmp($str1, $str2));
// int(0) 
```
if it returns 0 - strings are the same
if it returns something else - strings are different

Both of these are case-sensitive (So `Hello` isn't the same as `hello`)

For case-insensitive comparison, we can use `strcasecmp()` function
```php
$str1 = "hello";
$str2 = "Hello";

var_dump(strcasecmp($str1, $str2));
// int(0)
```

## Getting first/last letter

This sounds kind of hard, but we don't really need to break it into array using some loop - instead we can refer to the string like an array

So, to get a first letter from `$str1` just try to access it's field `0` - like this

```php
$str1 = "hello";

echo $str1[0];
// h 
```

Trying to access `1` will give us `e` and so on

But if we want to get last letter, how to do we do it? We don't have to know strings length - just start from the behind with `-1`
```php
$str1 = "hello";

echo $str1[-1];
// o 
```

`-2` would give us `l` and so on

## Strings length

There is a function for getting length of a string - `strlen()`
```php
$str1 = "hello";

echo strlen($str1);
// 5
```

## Converting string to array

Let's suppose we get a string with some comma-separated values
```
$str1 = "1, 2, 3, 4, 5, 6";
```

How can we convert it to array, like `[1, 2, 3, 4, 5, 6]` - No need for custom code - `explode()` is here
```php
$str1 = "1, 2, 3, 4, 5, 6";

var_dump(explode(", ", $str1));
// array(6) { [0]=> string(1) "1" [1]=> string(1) "2" [2]=> string(1) "3" [3]=> string(1) "4" [4]=> string(1) "5" [5]=> string(1) "6" } 
```

You see that magic? First argument is a separator, second is array.

If there is `explode()`, there is also `implode()` - convert from array to string

```php
$arr1 = [1, 2, 3, 4, 5, 6];

var_dump(implode(", ", $arr1));
// string(16) "1, 2, 3, 4, 5, 6" 
```

Simple as that

## Joining 2 strings

To join 2 string we use `.` operator in between them

So, if we have these 2 strings
```php
$str1 = "Hello ";
$str2 = "World!";
```

We can **concatenate** (join them together, another funny word) them with mentioned earlier operator

```php
echo $str1.$str2;
// Hello World! 
```

## Validating strings

This part is very important - so focus

There is one unwritten (Or right now written) rule - Never trust data passed by users

So basically treat every input as potentially harmful - like an attack

But can we defend? Of course, that's why we should be implementing some security solutions

I think we can divide them into 2 types

1. Sanitizing functions
2. Validating functions

### Sanitation

Sanitizing means - removing/replacing every possibly dangerous character with it's safe equivalent

There is one cool function, that will perfectly sanitize your string-type input - [`htmlentities()`](https://www.php.net/manual/en/function.htmlentities.php)

It will replace every dangerous character (like `<` or `>` and so on) with it's HTML entity

So for example, this code
```php
$str = "A 'quote' is <b>bold</b>";
echo htmlentities($str);
```

Will output:
```
 A 'quote' is &lt;b&gt;bold&lt;/b&gt;
```

Cool, but what about those quotes? No worries, that's why it takes second argument - **flags**

There are bunch of them - the whole list is in docs
The most popular is definitely **`ENT_QUOTES`** - except for `<` and `>` it will also convert both types of quotes into it's HTML entities

So now, after treating previous string with this function
```php
echo htmlentities($str, ENT_QUOTES);
```
We get
```php
// A &#039;quote&#039; is &lt;b&gt;bold&lt;/b&gt;
```

And for your information, yes this will output normally on the webpage - you will see text as it was in that variable

`htmlentities()` also takes third argument - encoding

That's pretty much, a information for the browser, how characters should be outputted onto your webpage - The most popular, and almost always working is `UTF-8` - so let's stick to it

And what about email addresses? Or IP addresses? What if we change something there - If we replace `@` in email, we won't be able to send anything

But, there is a way - with [`filter_var()`](https://www.php.net/manual/en/function.filter-var.php) function and `SANITIZE` filters

So, for example we have and email to sanitize

```php
$email = "jack@gmail.com"; 
```

To do it, we will use `FILTER_SANITIZE_EMAIL` filter

```php
$email = "jack@gmail.com";

filter_var($email, FILTER_SANITIZE_EMAIL);
```
This filter removes all characters except letters, digits and !#$%&'*+-=?^_{|}~@.[] - so everything that is banned in emails

The whole list of sanitizing filters can be found [here](https://www.php.net/manual/en/filter.filters.sanitize.php)

### Validation

And the second part of making inputs secure - validation

It's just checking - If types are correct, if format is correct etc.

To check types, we use designated functions - they follow the same pattern `is_[type]()` - for example

- is_bool($var) - is $var a boolean value?
- is_int($var) - is $var an int value?
- is_string($var) - is $var a string?
- is_array($var) - is $var an array value?

And so on, you get the drill

We can also use another method - know for us `filter_var()`, but with `VALIDATE` filters

Let's say, we have an IP and an email address

```php
$email = "jack@gmail.com";
$ip = "52.200.35.15";
```

We can validate if they are correct with `FILTER_VALIDATE_EMAIL` and `FILTER_VALIDATE_IP`

```php
if (filter_var($ip, FILTER_VALIDATE_IP)) {
    echo "This IP is valid";
}
echo "<br/>";
if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
   echo "This is valid email";
}
```

So, as you may have realized - These filters make function return either `true` or `false`

The whole list can be found [here](https://www.php.net/manual/en/filter.filters.validate.php) - There you can also learn, that with this method we can also validate types of passed data, check it out

There is also another option -  Regular Expressions, but I won't dive into it here, as this is a material for a fairly long article

And what about passwords? Do we handle them like normal strings? 

Not really - for a password to be safely stored, we need to **hash** it.

## Passwords and Hashing

Hashing is a method of non-reversible encryption - So you can't really decode hash

But how do we check passwords then?

We hash data passed by users, and compare it with hash from database.

There are many of those, some safer, some less. We should only use the newest ones, as older might be cracked and won't provide a good security measurements

And, how to we hash password? With [`password_hash()`](https://www.php.net/manual/en/function.password-hash.php) function

```php
$pass = "Password123";
echo password_hash($pass, PASSWORD_DEFAULT);
// $2y$10$m5kPJwmckipMn19qRHSNauT0bg.xnuT3mBNJXtJ1CGtIyVUWubVCO 
``` 

This function will often appear with 2 arguments
1. String to hash - here `$pass`
2. Algorithm - `PASSWORD_DEFAULT` means string will be hashed with default algorithm (Right now it's bcrypt, but it is designed to be changeable - as old algorithms are cracked, and new appear)

This might also take third argument - options 
Like memory cost or custom salt

What is salt? These are some random characters added to the string, before hashing to make it harder to crack. 

You can set your own, static salt. But it's recommended to leave it as it is, as it makes your passwords more secure

And how to compare it? Not with `==`, but with [`password_verify()`](https://www.php.net/manual/en/function.password-verify.php)

```php
$pass = "Password123";
$passwordHash = '$2y$10$m5kPJwmckipMn19qRHSNauT0bg.xnuT3mBNJXtJ1CGtIyVUWubVCO';

var_dump(password_verify($pass, $passwordHash));
// bool(true) 
```

As you see - it takes 2 arguments
1. Password in clear text
2. Hash

If passwords match - it returns `true`
If not - false

And that's how you handle passwords in PHP - we will utilize this later on, in our projects

## Conclusion

Thanks for reading. I hope you got the main point of strings, and how to use them. Also, if you have any feedback, that's what comments are for - I appreciate it all

Check out other parts of this series and my other articles

Again, thanks for reading. Wish you all the best in 2024 and see you in next articles