1 00:00:00,540 --> 00:00:03,790 The first new feature I want to cover is type declarations. 2 00:00:03,790 --> 00:00:07,850 This simply means specifying which type of variable is being set, 3 00:00:07,850 --> 00:00:10,700 instead of allowing PHP to set this automatically. 4 00:00:10,700 --> 00:00:14,450 PHP is considered a weak typed language. 5 00:00:14,450 --> 00:00:19,980 In essence, this means that PHP does not require that you declare the data types. 6 00:00:19,980 --> 00:00:25,420 Variables still have data types associated with them, but you can do radical things, 7 00:00:25,420 --> 00:00:28,450 like adding a string to an integer without resulting in an error. 8 00:00:29,480 --> 00:00:33,040 Type declarations can help you define what should occur, so 9 00:00:33,040 --> 00:00:35,270 that you get the expected results. 10 00:00:35,270 --> 00:00:37,810 This can also make your code easier to read. 11 00:00:37,810 --> 00:00:39,750 We'll look at some specific examples shortly. 12 00:00:40,920 --> 00:00:46,310 Since PHP5, you can use type hinting to specify the expected data types 13 00:00:46,310 --> 00:00:51,680 of an argument in a function declaration, but only in the declaration. 14 00:00:51,680 --> 00:00:54,390 When you call the function, PHP will check whether or 15 00:00:54,390 --> 00:00:57,640 not the arguments are of the specified type. 16 00:00:57,640 --> 00:01:02,570 If not, the runtime will raise an error and the execution will be halted. 17 00:01:02,570 --> 00:01:06,250 Besides only being used in function declarations, 18 00:01:06,250 --> 00:01:11,260 we are also limited to basically two types, a class name or an array. 19 00:01:12,290 --> 00:01:12,980 Here's an example. 20 00:01:14,410 --> 00:01:17,550 If we were to create a function for enrolling students, 21 00:01:17,550 --> 00:01:22,490 we would require that the first argument be an object of the class, Student, and 22 00:01:22,490 --> 00:01:25,920 the second argument to be an array of classes. 23 00:01:25,920 --> 00:01:29,900 If we tried to pass just the name of the student instead of an object, 24 00:01:29,900 --> 00:01:31,740 we would get a fatal error. 25 00:01:31,740 --> 00:01:35,950 If we were to pass a single class instead of an array of classes, 26 00:01:35,950 --> 00:01:38,180 we would also get an error. 27 00:01:38,180 --> 00:01:42,370 We are required to pass a student object and an array. 28 00:01:43,490 --> 00:01:49,466 If we were to try to check for a scalar variable, such as a string, PHP5 expects 29 00:01:49,466 --> 00:01:54,340 it to be an object of the class, string, not the variable type, string. 30 00:01:55,840 --> 00:01:59,470 With PHP7, we now have added scalar types. 31 00:01:59,470 --> 00:02:04,260 Specifically, int, float, string, and bool. 32 00:02:04,260 --> 00:02:08,380 By adding scalar type hints and enabling strict requirements, it is hoped 33 00:02:08,380 --> 00:02:13,060 that more correct and self-documenting PHP programs can be written. 34 00:02:13,060 --> 00:02:17,620 It also gives you more control over your code and can make the code easier to read. 35 00:02:18,880 --> 00:02:24,110 By default, scalar type declarations are non-strict, which means they attempt 36 00:02:24,110 --> 00:02:29,990 to change the original type to match the type specified in the type declaration. 37 00:02:29,990 --> 00:02:34,850 In other words, if you pass a string that starts with a number into a function that 38 00:02:34,850 --> 00:02:39,070 requires a float, it will grab the number from the beginning and 39 00:02:39,070 --> 00:02:40,990 remove everything else. 40 00:02:40,990 --> 00:02:46,470 Passing a float into a function that requires an int will become simply an int. 41 00:02:46,470 --> 00:02:49,730 Let's look at an example of a non-strict type. 42 00:02:49,730 --> 00:02:53,207 The getTotal function receives two floats and adds them together, 43 00:02:53,207 --> 00:02:55,470 while it returns the sum. 44 00:02:55,470 --> 00:02:59,180 Without strict types turned on, PHP attempts to cast or 45 00:02:59,180 --> 00:03:03,600 to change these arguments to match the type specified in the function. 46 00:03:03,600 --> 00:03:08,730 So when we call getTotal with non-strict types using an int of two and 47 00:03:08,730 --> 00:03:14,010 a string of one week, PHP converts these to floats, the first argument 48 00:03:14,010 --> 00:03:19,330 would be changed to 2.0, and the second argument would be changed to 1.0. 49 00:03:19,330 --> 00:03:23,206 However, you will get a notice because this is not a well formed numeric value. 50 00:03:23,206 --> 00:03:26,280 The function will then return a value of three, 51 00:03:26,280 --> 00:03:29,400 which would be completely wrong if we were trying to add days. 52 00:03:30,590 --> 00:03:35,548 When we call getTotal with the float 2.8 and the string of 3.2, 53 00:03:35,548 --> 00:03:39,822 PHP converts the string to the float 3.2 with no notice, 54 00:03:39,822 --> 00:03:43,110 because it was a smooth conversion. 55 00:03:43,110 --> 00:03:45,696 It then returns a value of six. 56 00:03:45,696 --> 00:03:51,092 When we call getTotal with non-strict types using the float 2.5, 57 00:03:51,092 --> 00:03:56,486 and the integer 1, the integer gets converted to the float 1.0 and 58 00:03:56,486 --> 00:03:58,900 the function returns 3.5. 59 00:03:58,900 --> 00:04:03,759 Additionally, PHP7 gives us the opportunity to enable strict mode 60 00:04:03,759 --> 00:04:06,200 on a file-by-file basis. 61 00:04:06,200 --> 00:04:10,220 We do this by declaring strict types at the top of any given file. 62 00:04:10,220 --> 00:04:14,770 This must be the very first line, even before name spaces. 63 00:04:14,770 --> 00:04:19,630 Declaring strict typing will ensure that any function call made in that file 64 00:04:19,630 --> 00:04:21,690 strictly adheres to the type specified. 65 00:04:22,790 --> 00:04:27,130 Strict is determined by the file in which the call to the function is made, 66 00:04:27,130 --> 00:04:29,940 not the file in which the function is defined. 67 00:04:29,940 --> 00:04:34,080 If a type declaration mismatch occurs, a fatal error is thrown, and 68 00:04:34,080 --> 00:04:36,930 we know that something is not functioning as desired. 69 00:04:36,930 --> 00:04:40,860 Instead of allowing PHP to simply guess at what we want to happen, 70 00:04:40,860 --> 00:04:46,290 allowing PHP to guess can cause seemingly random and hard to diagnose issues. 71 00:04:46,290 --> 00:04:49,130 We'll look at catching and handling errors in the next section. 72 00:04:49,130 --> 00:04:52,610 But for now, let's take a look at examples using strict types turned on. 73 00:04:53,680 --> 00:04:56,150 When declare strict type has been turned on, 74 00:04:56,150 --> 00:04:59,480 the first two calls that pass a string will produce a fatal error. 75 00:05:00,610 --> 00:05:03,496 The exception to strict typing is shown in the third call. 76 00:05:03,496 --> 00:05:07,253 If you pass an int as an argument that is looking for 77 00:05:07,253 --> 00:05:11,189 a float, PHP will perform what is called widening, 78 00:05:11,189 --> 00:05:16,122 by adding a dot zero to the end, and the function returns 3.5. 79 00:05:16,122 --> 00:05:19,608 PHP7 also supports return type declarations, 80 00:05:19,608 --> 00:05:23,016 which support all the same types as arguments. 81 00:05:23,016 --> 00:05:26,791 To specify the return type, we add a colon, and then the type, 82 00:05:26,791 --> 00:05:29,320 right before the opening curly bracket. 83 00:05:29,320 --> 00:05:34,190 If we specify the return type of float, it will work exactly like it has been working 84 00:05:34,190 --> 00:05:39,510 in the previous two examples, since the type being returned was already a float. 85 00:05:39,510 --> 00:05:44,120 Adding the return types allows you to be sure that your function returns what 86 00:05:44,120 --> 00:05:45,880 you expected to return, 87 00:05:45,880 --> 00:05:50,040 as well as make int easy to see up front how the function works. 88 00:05:50,040 --> 00:05:54,590 If we specify the return type as int without strict type set, 89 00:05:54,590 --> 00:05:58,080 everything will work the same as it did without a return type. 90 00:05:58,080 --> 00:06:01,920 The only difference is that it will force the return to be an int. 91 00:06:01,920 --> 00:06:05,920 In the third call, the return value will truncate to three 92 00:06:05,920 --> 00:06:07,720 because the floating point will be dropped. 93 00:06:09,090 --> 00:06:13,200 If we turn strict types on, we'll get a fatal type error. 94 00:06:13,200 --> 00:06:18,170 In this case, we'll need to specifically cast our return value as an int. 95 00:06:18,170 --> 00:06:20,500 This will then return the truncated value. 96 00:06:21,640 --> 00:06:24,900 The new type declarations can make code easier to read and 97 00:06:24,900 --> 00:06:28,150 forces things to be used the way they were intended. 98 00:06:28,150 --> 00:06:33,160 Some people prefer to use unit testing to check for intended use instead. 99 00:06:33,160 --> 00:06:36,590 Having automated tests for your code is highly recommended, but 100 00:06:36,590 --> 00:06:41,028 you can use both unit tests and type declarations working in harmony together. 101 00:06:41,028 --> 00:06:45,630 Either way, PHP does not require that you declare types, but 102 00:06:45,630 --> 00:06:49,050 it can definitely make code easier to read. 103 00:06:49,050 --> 00:06:52,976 You can see right at the start of a function what is required and 104 00:06:52,976 --> 00:06:54,195 what is returned. 105 00:06:54,195 --> 00:06:57,971 When you are working with declared types with strict types turned on, 106 00:06:57,971 --> 00:06:59,830 here are a few things to remember. 107 00:07:00,910 --> 00:07:07,570 Strict types are enabled or disabled per file, not a php.ini setting. 108 00:07:07,570 --> 00:07:11,730 Strict applies to the file in which the call to the function is made, 109 00:07:11,730 --> 00:07:13,930 not the file in which the function is defined. 110 00:07:15,060 --> 00:07:17,899 If strict is defined in test.php, 111 00:07:17,899 --> 00:07:22,736 all function calls made from test.php have strict typing. 112 00:07:22,736 --> 00:07:26,391 Integers will be widened into floats by adding dot zero. 113 00:07:26,391 --> 00:07:28,700 All other type conversions will error.