Initial commit for public repo
4
.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
.DS_Store
|
||||
|
||||
/vendor
|
||||
/node_modules
|
13
LICENSE.md
Normal file
@@ -0,0 +1,13 @@
|
||||
Copyright 2018 Andrew Davis <andrew@restoredsoftware.com>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
2
README.md
Normal file
@@ -0,0 +1,2 @@
|
||||
# PHP Apprentice
|
||||
The source code for a website about learning PHP.
|
8
apprentice
Normal file
@@ -0,0 +1,8 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
require __DIR__ . '/vendor/autoload.php';
|
||||
|
||||
load_config(__DIR__ . '/config.php');
|
||||
|
||||
$app = new Apprentice\App;
|
||||
$app->main();
|
217
assets/css/site.css
Normal file
@@ -0,0 +1,217 @@
|
||||
@import "prismjs/themes/prism-solarizedlight.css";
|
||||
|
||||
$primary-color: #2AA198;
|
||||
$primary-color-dark: #1D6E68;
|
||||
$white: #FFF;
|
||||
$drop-shadow: rgba(0, 0, 0, 0.4);
|
||||
$code-background: #FDF6E3;
|
||||
|
||||
body {
|
||||
font-family: Palatino, "Palatino Linotype", "Palatino LT STD", "Book Antiqua", Georgia, serif;
|
||||
font-size: 16px;
|
||||
padding-top: 1em;
|
||||
padding-bottom: 1em;
|
||||
}
|
||||
pre, code {
|
||||
font-family: Consolas, monaco, monospace;
|
||||
font-size: 16px;
|
||||
margin: 0 !important;
|
||||
border-radius: 0 !important;
|
||||
padding-top: 0.5em !important;
|
||||
padding-bottom: 0.5em !important;
|
||||
}
|
||||
a {
|
||||
color: $primary-color; /* #4078f2 */
|
||||
text-decoration: none;
|
||||
}
|
||||
a:hover {
|
||||
text-decoration: underline;
|
||||
color: $primary-color-dark;
|
||||
}
|
||||
p {
|
||||
max-width: 40em;
|
||||
line-height: 1.5;
|
||||
}
|
||||
h1, h2, h3, h4 {
|
||||
margin: 1.414em 0 0.5em;
|
||||
font-weight: inherit;
|
||||
line-height: 1.2;
|
||||
}
|
||||
h1 {
|
||||
margin-top: 0;
|
||||
font-size: 2.441em;
|
||||
}
|
||||
h2 {font-size: 1.953em;}
|
||||
h3 {font-size: 1.563em;}
|
||||
h4 {font-size: 1.25em;}
|
||||
small, .font_small {font-size: 0.8em;}
|
||||
button {
|
||||
font-size: 1em;
|
||||
background-color: transparent;
|
||||
border: 0;
|
||||
cursor: pointer;
|
||||
padding: 0;
|
||||
color: $primary-color;
|
||||
}
|
||||
button:hover {
|
||||
color: $primary-color-dark;
|
||||
}
|
||||
button .icon {
|
||||
vertical-align: middle;
|
||||
}
|
||||
button .icon svg {
|
||||
fill: $primary-color;
|
||||
}
|
||||
button:hover .icon svg {
|
||||
fill: $primary-color-dark;
|
||||
}
|
||||
.button {
|
||||
background-color: $primary-color;
|
||||
color: $white;
|
||||
padding: 0.5em 1em;
|
||||
border-radius: 1em;
|
||||
}
|
||||
.button:hover {
|
||||
color: $white;
|
||||
background-color: $primary-color-dark;
|
||||
text-decoration: none;
|
||||
}
|
||||
.button .icon {
|
||||
vertical-align: middle;
|
||||
}
|
||||
.button .icon svg {
|
||||
fill: $white;
|
||||
}
|
||||
.clearfix:after {
|
||||
content: "";
|
||||
display: table;
|
||||
clear: both;
|
||||
}
|
||||
.container {
|
||||
width: 90%;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
@media only screen and (min-width: 33.75em) { /* 540px */
|
||||
.container {
|
||||
width: 80%;
|
||||
}
|
||||
}
|
||||
.center {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
.right {
|
||||
float: right;
|
||||
}
|
||||
.doc {
|
||||
padding: 0.5em 0;
|
||||
}
|
||||
.subtitle {
|
||||
margin-top: 0;
|
||||
}
|
||||
.description {
|
||||
max-width: 25em;
|
||||
}
|
||||
.grid-code {
|
||||
display: grid;
|
||||
grid-template-columns: 400px 1fr;
|
||||
grid-column-gap: 3em;
|
||||
}
|
||||
.grid-code .code {
|
||||
background-color: $code-background;
|
||||
}
|
||||
.grid-toc {
|
||||
display: grid;
|
||||
grid-template-columns: 2fr 1fr;
|
||||
grid-column-gap: 3em;
|
||||
}
|
||||
.navigate-links {
|
||||
margin: 1em 0;
|
||||
float: right;
|
||||
}
|
||||
.navigate-links .icon {
|
||||
vertical-align: middle;
|
||||
}
|
||||
.navigate-links .icon svg {
|
||||
fill: $primary-color;
|
||||
}
|
||||
.navigate-links:hover .icon svg {
|
||||
fill: $primary-color-dark;
|
||||
}
|
||||
.navigate-links a {
|
||||
margin-left: 1em;
|
||||
}
|
||||
.navigate-links a:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
.table-of-contents {
|
||||
padding: 2em;
|
||||
}
|
||||
.table-of-contents ol {
|
||||
margin: 1em 0;
|
||||
padding-left: 1em;
|
||||
}
|
||||
.table-of-contents .section-title {
|
||||
font-weight: bold;
|
||||
font-size: 0.8em;
|
||||
margin-top: 1em;
|
||||
}
|
||||
.icon {
|
||||
width: 1em;
|
||||
display: inline-block;
|
||||
}
|
||||
.home-title-wrapper {
|
||||
display: grid;
|
||||
grid-template-columns: 175px 1fr;
|
||||
grid-template-rows: 1fr 1fr;
|
||||
}
|
||||
.home-title {
|
||||
|
||||
}
|
||||
.home-subtitle {
|
||||
margin-top: 0;
|
||||
grid-column-start: 2;
|
||||
grid-column-end: 3;
|
||||
}
|
||||
.home-logo {
|
||||
grid-row-start: 1;
|
||||
grid-row-end: 3;
|
||||
}
|
||||
.home-logo svg {
|
||||
width: 150px;
|
||||
height: 100px;
|
||||
}
|
||||
.menu {
|
||||
margin-left: 2em;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
.modal {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 50;
|
||||
overflow: auto;
|
||||
background-color: rgba(0, 0, 0, .4);
|
||||
}
|
||||
.modal-content {
|
||||
display: block;
|
||||
position: relative;
|
||||
padding: 1em;
|
||||
background-color: $white;
|
||||
max-width: 15em;
|
||||
height: 100%;
|
||||
animation-name: animateleft;
|
||||
animation-duration: .4s;
|
||||
overflow: scroll;
|
||||
box-shadow: 0 0 10px 0 $drop-shadow;
|
||||
}
|
||||
.closed {
|
||||
display: none;
|
||||
}
|
||||
@keyframes animateleft {
|
||||
from {left: -300px; opacity: 0}
|
||||
to {left: 0; opacity: 1}
|
||||
}
|
1
assets/icons/arrow-thin-down.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M9 16.172l-6.071-6.071-1.414 1.414L10 20l.707-.707 7.778-7.778-1.414-1.414L11 16.172V0H9z"/></svg>
|
After Width: | Height: | Size: 167 B |
1
assets/icons/arrow-thin-left.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M3.828 9l6.071-6.071-1.414-1.414L0 10l.707.707 7.778 7.778 1.414-1.414L3.828 11H20V9H3.828z"/></svg>
|
After Width: | Height: | Size: 169 B |
1
assets/icons/arrow-thin-right.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M16.172 9l-6.071-6.071 1.414-1.414L20 10l-.707.707-7.778 7.778-1.414-1.414L16.172 11H0V9z"/></svg>
|
After Width: | Height: | Size: 167 B |
1
assets/icons/arrow-thin-up.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M9 3.828L2.929 9.899 1.515 8.485 10 0l.707.707 7.778 7.778-1.414 1.414L11 3.828V20H9V3.828z"/></svg>
|
After Width: | Height: | Size: 169 B |
1
assets/icons/book-reference.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M6 4H5a1 1 0 1 1 0-2h11V1a1 1 0 0 0-1-1H4a2 2 0 0 0-2 2v16c0 1.1.9 2 2 2h12a2 2 0 0 0 2-2V5a1 1 0 0 0-1-1h-7v8l-2-2-2 2V4z"/></svg>
|
After Width: | Height: | Size: 200 B |
1
assets/icons/cheveron-outline-down.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M20 10a10 10 0 1 1-20 0 10 10 0 0 1 20 0zM10 2a8 8 0 1 0 0 16 8 8 0 0 0 0-16zm-.7 10.54L5.75 9l1.41-1.41L10 10.4l2.83-2.82L14.24 9 10 13.24l-.7-.7z"/></svg>
|
After Width: | Height: | Size: 225 B |
1
assets/icons/cheveron-outline-left.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M10 20a10 10 0 1 1 0-20 10 10 0 0 1 0 20zm8-10a8 8 0 1 0-16 0 8 8 0 0 0 16 0zM7.46 9.3L11 5.75l1.41 1.41L9.6 10l2.82 2.83L11 14.24 6.76 10l.7-.7z"/></svg>
|
After Width: | Height: | Size: 223 B |
1
assets/icons/cheveron-outline-right.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M10 0a10 10 0 1 1 0 20 10 10 0 0 1 0-20zM2 10a8 8 0 1 0 16 0 8 8 0 0 0-16 0zm10.54.7L9 14.25l-1.41-1.41L10.4 10 7.6 7.17 9 5.76 13.24 10l-.7.7z"/></svg>
|
After Width: | Height: | Size: 221 B |
1
assets/icons/cheveron-outline-up.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M0 10a10 10 0 1 1 20 0 10 10 0 0 1-20 0zm10 8a8 8 0 1 0 0-16 8 8 0 0 0 0 16zm.7-10.54L14.25 11l-1.41 1.41L10 9.6l-2.83 2.8L5.76 11 10 6.76l.7.7z"/></svg>
|
After Width: | Height: | Size: 222 B |
1
assets/icons/close-outline.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M2.93 17.07A10 10 0 1 1 17.07 2.93 10 10 0 0 1 2.93 17.07zm1.41-1.41A8 8 0 1 0 15.66 4.34 8 8 0 0 0 4.34 15.66zm9.9-8.49L11.41 10l2.83 2.83-1.41 1.41L10 11.41l-2.83 2.83-1.41-1.41L8.59 10 5.76 7.17l1.41-1.41L10 8.59l2.83-2.83 1.41 1.41z"/></svg>
|
After Width: | Height: | Size: 314 B |
1
assets/icons/close-solid.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M2.93 17.07A10 10 0 1 1 17.07 2.93 10 10 0 0 1 2.93 17.07zM11.4 10l2.83-2.83-1.41-1.41L10 8.59 7.17 5.76 5.76 7.17 8.59 10l-2.83 2.83 1.41 1.41L10 11.41l2.83 2.83 1.41-1.41L11.41 10z"/></svg>
|
After Width: | Height: | Size: 260 B |
1
assets/icons/close.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M10 8.586L2.929 1.515 1.515 2.929 8.586 10l-7.071 7.071 1.414 1.414L10 11.414l7.071 7.071 1.414-1.414L11.414 10l7.071-7.071-1.414-1.414L10 8.586z"/></svg>
|
After Width: | Height: | Size: 223 B |
42
assets/icons/elephant.svg
Normal file
@@ -0,0 +1,42 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="404px" height="249px" viewBox="0 0 404 249" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 49.3 (51167) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>elephant</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<defs>
|
||||
<path d="M114.406262,33.0409234 C116.906654,33.0409234 198.587086,33.0409234 212.851562,33.0409234 C236.23173,33.0409234 290.966457,24.8360253 302.9375,21.828125 C322.709617,16.8600902 345.780295,41.1710486 350.739426,66.2834373 C355.388936,89.8279414 351.557615,107.060167 350.739426,117.478001 C348.492267,146.090655 340.913827,171.751032 340.913827,188.521289 C340.913827,211.397578 342.398654,228.60813 345.368307,240.152946 C338.345502,243.384315 332.63113,245 328.225191,245 C323.819252,245 319.466187,243.384315 315.165998,240.152946 C315.165998,212.852821 315.165998,195.642269 315.165998,188.521289 C315.165998,182.659437 313.041474,171.488839 308.792425,155.009494 C278.81585,157.935469 251.486979,159.893283 226.805814,160.882937 C202.124648,161.87259 177.935757,159.914776 154.23914,155.009494 C151.904793,170.439973 150.468074,183.375856 149.928982,193.817144 C149.389891,204.258431 148.391339,219.703699 146.933325,240.152946 C138.57305,243.384315 132.573934,245 128.935979,245 C125.298024,245 120.454785,243.384315 114.406262,240.152946 C121.029663,211.242836 124.190445,189.722491 123.888609,175.59191 C122.851956,127.060632 111.761968,33.0409234 114.406262,33.0409234 Z" id="path-1"></path>
|
||||
<filter x="-2.7%" y="-2.0%" width="103.8%" height="104.0%" filterUnits="objectBoundingBox" id="filter-2">
|
||||
<feMorphology radius="0.5" operator="dilate" in="SourceAlpha" result="shadowSpreadOuter1"></feMorphology>
|
||||
<feOffset dx="-2" dy="0" in="shadowSpreadOuter1" result="shadowOffsetOuter1"></feOffset>
|
||||
<feGaussianBlur stdDeviation="1" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
|
||||
<feComposite in="shadowBlurOuter1" in2="SourceAlpha" operator="out" result="shadowBlurOuter1"></feComposite>
|
||||
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
|
||||
</filter>
|
||||
<path d="M123.708835,0.204671096 C110.38422,-0.782948431 96.8541352,1.80367512 83.1185794,7.96454174 C70.5914337,12.5905258 61.8564763,19.2306573 56.9137071,27.8849362 C45.3780726,48.0826419 45.2190029,54.1139776 45.2190029,74.89832 C45.2190029,80.5496319 45.2190029,94.2775295 45.2190029,116.082013 C44.8941776,135.814054 42.9028153,149.847335 39.2449159,158.181856 C35.7666671,166.107044 22.7617193,171.939345 0.23007254,175.678759 C0.0766908466,178.530744 -4.04672828e-16,180.785883 0,182.444176 C-4.04672828e-16,184.102469 0.742211413,186.619924 2.22663424,189.996543 C19.3683356,190.134613 33.6991251,186.137222 45.2190029,178.004371 C58.0689401,168.932519 56.2252902,163.797983 62.486142,147.454285 C66.2191971,137.709297 68.3704403,127.251873 68.9398717,116.082013 C98.4645478,120.955097 116.720869,123.391639 123.708835,123.391639 C134.190784,123.391639 148.793717,120.923091 160.10709,103.338129 C171.533853,85.5769196 172.420694,75.0592376 174.453335,67.1621734 C177.277215,56.1910529 186,34.1766174 186,21.1547558 C186,8.13289413 144.421355,1.73988173 123.708835,0.204671096 Z" id="path-3"></path>
|
||||
<filter x="-1.9%" y="-1.3%" width="104.8%" height="104.7%" filterUnits="objectBoundingBox" id="filter-4">
|
||||
<feMorphology radius="0.5" operator="dilate" in="SourceAlpha" result="shadowSpreadOuter1"></feMorphology>
|
||||
<feOffset dx="1" dy="2" in="shadowSpreadOuter1" result="shadowOffsetOuter1"></feOffset>
|
||||
<feGaussianBlur stdDeviation="1" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
|
||||
<feComposite in="shadowBlurOuter1" in2="SourceAlpha" operator="out" result="shadowBlurOuter1"></feComposite>
|
||||
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
|
||||
</filter>
|
||||
</defs>
|
||||
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="Elephant" transform="translate(-120.000000, -62.000000)">
|
||||
<g id="elephant" transform="translate(122.000000, 63.000000)">
|
||||
<path d="M292,154 L292,229.687017 C297.80012,232.562339 302.466787,234 306,234 C309.533213,234 314.19988,232.562339 320,229.687017 L320,154 L292,154 Z" id="Path-3" stroke="#979797" fill="#D8D8D8"></path>
|
||||
<path d="M113.089613,112 C112.215697,146.301082 110.868891,171.05041 109.049195,186.247987 C107.229499,201.445563 103.879767,215.920359 99,229.672376 C104.837247,232.557459 109.533784,234 113.089613,234 C116.645442,234 121.34198,232.557459 127.179226,229.672376 L134,112 L113.089613,112 Z" id="Path-3-Copy" stroke="#979797" fill="#D8D8D8"></path>
|
||||
<g id="Path">
|
||||
<use fill="black" fill-opacity="1" filter="url(#filter-2)" xlink:href="#path-1"></use>
|
||||
<use stroke="#979797" stroke-width="1" fill="#D8D8D8" fill-rule="evenodd" xlink:href="#path-1"></use>
|
||||
</g>
|
||||
<g id="Path-2">
|
||||
<use fill="black" fill-opacity="1" filter="url(#filter-4)" xlink:href="#path-3"></use>
|
||||
<use stroke="#979797" stroke-width="1" fill="#D8D8D8" fill-rule="evenodd" xlink:href="#path-3"></use>
|
||||
</g>
|
||||
<circle id="Oval" fill="#000000" cx="77" cy="76" r="5"></circle>
|
||||
<path d="M394.04451,154.695284 C387.335643,135.817928 382.463422,123.3603 379.427845,117.322398 C376.392268,111.284497 366.955141,94.8960125 351.116464,68.1569449 L353,83.4050009 C362.468082,99.4723027 368.913046,110.778102 372.334893,117.322398 C380.679064,133.280662 386.198146,152.11787 388.617876,158.078886 C390.422602,162.524839 392.314008,171.103712 394.04451,185.164806 C394.940381,192.444154 397.167522,203.5 399.948259,203.5 C402.726203,203.5 400.982103,193.180619 399.948259,185.164806 C399.25903,179.820931 397.291114,169.664424 394.04451,154.695284 Z" id="Path-4" stroke="#979797" fill="#D8D8D8"></path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 6.1 KiB |
1
assets/icons/list-bullet.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M1 4h2v2H1V4zm4 0h14v2H5V4zM1 9h2v2H1V9zm4 0h14v2H5V9zm-4 5h2v2H1v-2zm4 0h14v2H5v-2z"/></svg>
|
After Width: | Height: | Size: 162 B |
1
assets/icons/menu.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M0 3h20v2H0V3zm0 6h20v2H0V9zm0 6h20v2H0v-2z"/></svg>
|
After Width: | Height: | Size: 121 B |
63
assets/js/site.js
Normal file
@@ -0,0 +1,63 @@
|
||||
import Prism from 'prismjs';
|
||||
|
||||
var onLoad = function () {
|
||||
Prism.highlightAll();
|
||||
|
||||
var menuButton = document.querySelector('.menu-button');
|
||||
|
||||
// stop execution if menu button does not exist on page
|
||||
if (!menuButton) {
|
||||
return;
|
||||
}
|
||||
|
||||
var modalButton = document.querySelector('.modal-button');
|
||||
var modal = document.querySelector('.modal');
|
||||
var modalContent = document.querySelector('.modal-content');
|
||||
var clickEvent = function (e) {
|
||||
var modal = document.querySelector('.modal');
|
||||
|
||||
if (modal.classList.contains('closed')) {
|
||||
modal.classList.remove('closed')
|
||||
} else {
|
||||
modal.classList.add('closed')
|
||||
}
|
||||
};
|
||||
|
||||
menuButton.addEventListener('click', clickEvent);
|
||||
modalButton.addEventListener('click', clickEvent);
|
||||
modal.addEventListener('click', function (e) {
|
||||
var target = e.target
|
||||
do {
|
||||
if (target == modalContent) {
|
||||
return;
|
||||
}
|
||||
target = target.parentNode;
|
||||
} while (target);
|
||||
|
||||
modal.classList.add('closed')
|
||||
});
|
||||
};
|
||||
|
||||
document.onkeydown = function (e) {
|
||||
e = e || window.event;
|
||||
|
||||
var isEscape = false;
|
||||
if ("key" in e) {
|
||||
isEscape = (e.key == "Escape" || e.key == "Esc");
|
||||
} else {
|
||||
isEscape = (e.keyCode == 27);
|
||||
}
|
||||
|
||||
if (isEscape) {
|
||||
var modal = document.querySelector('.modal');
|
||||
if (modal && !modal.classList.contains('closed')) {
|
||||
modal.classList.add('closed');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (document.readyState !== 'loading') {
|
||||
onLoad();
|
||||
} else {
|
||||
document.addEventListener('DOMContentLoaded', onLoad);
|
||||
}
|
3
assets/templates/_footer.phtml
Normal file
@@ -0,0 +1,3 @@
|
||||
</body>
|
||||
|
||||
</html>
|
15
assets/templates/_header.phtml
Normal file
@@ -0,0 +1,15 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<title><?= $title ?? 'PHP Apprentice' ?></title>
|
||||
<meta name="description" content="<?= $description ?? 'A site for learning how to use PHP'?>">
|
||||
|
||||
<link rel="stylesheet" href="/css/site.css">
|
||||
<link rel="icon" href="/favicon-32.png">
|
||||
<script src="/js/site.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
17
assets/templates/_table_of_contents.phtml
Normal file
@@ -0,0 +1,17 @@
|
||||
<div class="table-of-contents">
|
||||
<h4>Table of Contents</h4>
|
||||
<a href="<?= page_path('index') ?>">Preface</a>
|
||||
<ol>
|
||||
<li><a href="<?= page_path('basics') ?>">Basics</a></li>
|
||||
<li><a href="<?= page_path('variables') ?>">Variables</a></li>
|
||||
<li><a href="<?= page_path('arithmetic') ?>">Arithmetic</a></li>
|
||||
<li><a href="<?= page_path('comparisons') ?>">Comparisons</a></li>
|
||||
<li><a href="<?= page_path('boolean-logic') ?>">Boolean Logic</a></li>
|
||||
<li><a href="<?= page_path('conditionals') ?>">Conditionals</a></li>
|
||||
<li><a href="<?= page_path('loops') ?>">Loops</a></li>
|
||||
<li><a href="<?= page_path('arrays') ?>">Arrays</a></li>
|
||||
<li><a href="<?= page_path('functions') ?>">Functions</a></li>
|
||||
<li><a href="<?= page_path('classes') ?>">Classes</a></li>
|
||||
</ol>
|
||||
<a href="<?= page_path('credits') ?>">Credits</a>
|
||||
</div>
|
19
assets/templates/credits.phtml
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php partial('header', ['title' => 'PHP Apprentice - Credits']) ?>
|
||||
|
||||
<div class="container center">
|
||||
<div class="grid-toc">
|
||||
<div>
|
||||
<h1>Credits</h1>
|
||||
<p>
|
||||
PHP Apprentice was inspired by
|
||||
<a href="https://gobyexample.com/">Go By Example</a> and by <a href="https://elixirschool.com/">Elixir School</a>. Both sites offer excellent, quality documentation in Go and Elixir and I want PHP Apprentice to provide the same
|
||||
experience for the PHP programming language.
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<?php partial('table_of_contents') ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php partial('footer') ?>
|
41
assets/templates/default.phtml
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php partial('header', ['title' => $title, 'description' => $description]) ?>
|
||||
|
||||
<div class="menu">
|
||||
<button class="menu-button" title="Open Menu">
|
||||
<div class="icon"><?= icon('menu') ?></div>
|
||||
Menu
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="container center">
|
||||
<h1><?= escape($title) ?></h1>
|
||||
<h3 class="subtitle"><?= escape($subtitle) ?></h3>
|
||||
<?= code_table($code) ?>
|
||||
|
||||
<div class="clearfix"></div>
|
||||
<div class="navigate-links">
|
||||
<?php if (!empty($previous)): ?>
|
||||
<a href="<?= page_path($previous) ?>" title="Previous">
|
||||
<div class="icon"><?= icon('cheveron-outline-left') ?></div>
|
||||
Previous
|
||||
</a>
|
||||
<?php endif ?>
|
||||
<?php if (!empty($next)): ?>
|
||||
<a href="<?= page_path($next) ?>" title="Next">
|
||||
Next
|
||||
<div class="icon"><?= icon('cheveron-outline-right') ?></div>
|
||||
</a>
|
||||
<?php endif ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal closed">
|
||||
<div class="modal-content">
|
||||
<button class="modal-button right" title="Close">
|
||||
<div class="icon"><?= icon('close-outline') ?></div>
|
||||
</button>
|
||||
<?php partial('table_of_contents') ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php partial('footer') ?>
|
36
assets/templates/index.phtml
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php partial('header', ['title' => 'PHP Apprentice']) ?>
|
||||
|
||||
<div class="container center">
|
||||
<div class="grid-toc">
|
||||
<div>
|
||||
<div class="home-title-wrapper">
|
||||
<div class="home-logo"><?= icon('elephant') ?></div>
|
||||
<h1 class="home-title">PHP Apprentice <em>(beta)</em></h1>
|
||||
<h3 class="home-subtitle">A site for learning how to use PHP</h3>
|
||||
</div>
|
||||
<p>
|
||||
The goal of PHP Apprentice is to be an easy to understand resource for learning how to write good code in the PHP programming language. There are a lot of PHP tutorials on the internet that use outdated libraries, insecure programming practices or inefficient code. I want this site to show how to write PHP code with quality.
|
||||
</p>
|
||||
<p>
|
||||
The site currently has content for learning the basics of PHP. In the future, more pages will be added for more advanced topics like building websites, database integration and security.
|
||||
</p>
|
||||
<p>
|
||||
PHP Apprentice is currently a work in progress (hence "beta" is included in the title). If you would like to contribute or request a certain discussion topic, checkout the <a href="https://github.com/restoreddev/php-apprentice" target="_blank">GitHub repository</a>.
|
||||
</p>
|
||||
<p>
|
||||
To get started, you will need to install PHP 7.1, have a text editor and open your terminal.
|
||||
Each example in PHP Apprentice can by typed into a PHP file and executed in the terminal.
|
||||
Let's get started! 😃
|
||||
</p>
|
||||
<a href="<?= page_path('basics') ?>" class="button">
|
||||
<div class="icon"><?= icon('book-reference') ?></div>
|
||||
Open First Chapter
|
||||
</a>
|
||||
</div>
|
||||
<div>
|
||||
<?php partial('table_of_contents') ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php partial('footer') ?>
|
26
code/arithmetic.php
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
// Now that we know how to create variables, let's look at doing some math.
|
||||
$a = 1;
|
||||
$b = 2;
|
||||
|
||||
// To add two values, use the plus symbol.
|
||||
$c = $a + $b;
|
||||
|
||||
// To subtract, use the minus symbol.
|
||||
$c = $b - $a;
|
||||
|
||||
// To multiply two values, use an asterisk.
|
||||
echo $a * $b;
|
||||
|
||||
// To divide values, use a forward slash.
|
||||
echo $b / $a;
|
||||
|
||||
// PHP uses the percent symbol for calculating the modulus of two numbers.
|
||||
// The modulus is calculated by dividing two numbers and returning the remainder of the result.
|
||||
// So, in this example, the value of $modulo will be 0.
|
||||
$modulo = 10 % 5;
|
||||
|
||||
// You can also use double asterisks to calculate a number to the power of another number.
|
||||
// The following statement will print 25.
|
||||
echo 5 ** 2;
|
26
code/arrays.php
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
// There are two ways to create an array.
|
||||
// First, you can use the array construct to pass in values separated by commas
|
||||
// and it will return an array.
|
||||
$taskList = array('grocery store', 'change car oil');
|
||||
|
||||
// Second, you can surround the list in square brackets.
|
||||
// This style is the most common and recommended form
|
||||
// of creating an array.
|
||||
$groceryList = ['bread', 'milk', 'eggs'];
|
||||
|
||||
// PHP will automatically assign index keys for each value in an array
|
||||
// starting with 0. So, to access a value in an array you will
|
||||
// pass the key number into brackets after the variable name.
|
||||
echo $groceryList[0] . "\n";
|
||||
echo $groceryList[1] . "\n";
|
||||
|
||||
// You can also assign keys in an array using numbers or strings.
|
||||
// It is very common to create an array with string keys. The pattern
|
||||
// is called an associative array or a map.
|
||||
$car = ['make' => 'Toyota', 'model' => 'Camry'];
|
||||
|
||||
// To access the value in an associative array, just use the string key in brackets
|
||||
// after the variable name.
|
||||
echo $car['model'] . "\n";
|
25
code/basics.php
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
// In the tradition of our ancestors, let's start with a hello world program.
|
||||
// All PHP files must start with a <?php tag unless it is for a html template.
|
||||
// (We will learn about html templates later.)
|
||||
echo "Hello World!\n";
|
||||
|
||||
// There is a lot going on in this statement so let's work through it.
|
||||
|
||||
// First, the echo keyword tells PHP to output some text.
|
||||
echo 'I am some text';
|
||||
|
||||
// Second, PHP stores text in strings.
|
||||
|
||||
// To write a string, you surround letters with single or double quotes.
|
||||
// The difference between single quoted strings and double quoted strings
|
||||
// is that double quoted strings can hold special characters like \n which tells PHP to start a new line.
|
||||
'I am a string';
|
||||
"\nI am a string on a new line";
|
||||
|
||||
// Third, all lines of code in PHP must end in a semi-colon.
|
||||
echo "No semi-colon is a no-no\n";
|
||||
|
||||
// Using semi-colons means we can write multiple statements on one line.
|
||||
echo 'Hello'; echo " World\n";
|
35
code/boolean-logic.php
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
// Boolean logic is used to combine booleans to return another boolean.
|
||||
|
||||
// Using double ampersands tells PHP to check if both values are true.
|
||||
// If so, it will return true. If not, it will return false.
|
||||
$a = true;
|
||||
$b = true;
|
||||
$c = false;
|
||||
|
||||
// Returns true.
|
||||
$a && $b;
|
||||
// Returns false.
|
||||
$a && $c;
|
||||
|
||||
// Using two pipe characters checks if either value is true.
|
||||
// Then, it will return true. If both values are false, the PHP
|
||||
// returns false.
|
||||
$a = true;
|
||||
$b = false;
|
||||
$c = false;
|
||||
$d = true;
|
||||
|
||||
// Returns true.
|
||||
$a || $b;
|
||||
// Returns false.
|
||||
$b || $c;
|
||||
// Returns true.
|
||||
$a || $d;
|
||||
|
||||
// Using an exclamation point returns the value flipped.
|
||||
$d = true;
|
||||
|
||||
// Outputs false.
|
||||
echo !$d;
|
42
code/classes.php
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
// Classes allow you to define your own data types. All classes start with the
|
||||
// class keyword followed by the name of the class and opening and closing curly braces.
|
||||
class Car
|
||||
{
|
||||
}
|
||||
|
||||
// To create an instance of a class, you use the "new" keyword in front of the class name
|
||||
// with parentheses.
|
||||
$car = new Car();
|
||||
|
||||
// A class can define attributes and methods. An attribute is a piece of data
|
||||
// stored on the class instance. You can define an attribute by adding the
|
||||
// word "public" and a variable name inside the class definition.
|
||||
class Bicycle
|
||||
{
|
||||
public $color;
|
||||
}
|
||||
|
||||
// Then, when you create an instance of the class, you can set and use
|
||||
// the color attribute on the bicycle using "->".
|
||||
$bike = new Bicycle();
|
||||
$bike->color = 'Blue';
|
||||
echo $bike->color . "\n";
|
||||
|
||||
// A method is a function attached to the class. You can add a method
|
||||
// to a class by using the "public" keyword followed by the function. A method
|
||||
// can access the attributes and methods of the instance using the "$this" variable.
|
||||
class Tricycle
|
||||
{
|
||||
public $color;
|
||||
|
||||
public function echoColor()
|
||||
{
|
||||
echo $this->color . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
$bike = new Tricycle();
|
||||
$bike->color = 'Red';
|
||||
$bike->echoColor();
|
41
code/comparisons.php
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
// A boolean is a value that is always 0 or 1, yes or no, on or off.
|
||||
// In PHP, a boolean is represented by the words true and false.
|
||||
// While programming, you will often want to know if something is true or false.
|
||||
$a = true;
|
||||
$b = false;
|
||||
|
||||
// There are many constructs and functions that will return a boolean.
|
||||
// To start, let's look at comparisons.
|
||||
$one = 1;
|
||||
$two = 2;
|
||||
|
||||
// Double equals checks if two values are equal.
|
||||
// This statement will return false.
|
||||
$one == $two;
|
||||
|
||||
// An exclamation point and equal sign check if two values are not equal.
|
||||
// This statement will return true.
|
||||
$one != $two;
|
||||
|
||||
// You can use greater than and less than symbols to check for comparisons too.
|
||||
// This statement will return false.
|
||||
$one > $two;
|
||||
|
||||
// This statement will return true.
|
||||
$one < $two;
|
||||
|
||||
// If you combine a greater than or less than symbol with an equal,
|
||||
// it will check if the value is greater or less than or equal to another value.
|
||||
$one <= $two;
|
||||
$one >= $two;
|
||||
|
||||
// You can also check that two values are equal and of the same type
|
||||
// by using three equal signs.
|
||||
|
||||
// This returns true.
|
||||
1 == '1';
|
||||
|
||||
// This returns false.
|
||||
1 === '1';
|
70
code/conditionals.php
Normal file
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
// When writing code, there will be times when you need to perform actions only under certain circumstances.
|
||||
// There are several ways to control execution in PHP.
|
||||
// We will start with an if statement.
|
||||
$animal = 'cow';
|
||||
if ($animal == 'cow') {
|
||||
echo "Moooooo.....\n";
|
||||
}
|
||||
|
||||
// All conditionals check to see if a statement evaluates to true or false.
|
||||
// In the case above, since $animal equals 'cow', the statement returns true and the contents of the if statement are executed.
|
||||
|
||||
|
||||
// An if statement can have multiple conditions chained together.
|
||||
// If the first if statement returns false, then PHP will check each elseif.
|
||||
// If none of the checks return true, then the else block will be executed.
|
||||
$animal = 'bird';
|
||||
if ($animal == 'dog') {
|
||||
echo "Woof! 🐶\n";
|
||||
} elseif ($animal == 'cat') {
|
||||
echo "Meow!? 🐱\n";
|
||||
} elseif ($animal == 'bird') {
|
||||
echo "Chirp! 🐦\n";
|
||||
} else {
|
||||
echo "I am not a dog, cat or bird\n";
|
||||
}
|
||||
|
||||
// An alternative to the if statement is the switch.
|
||||
// A switch statement has multiple cases to check if the value in parentheses equals something.
|
||||
// In this statement, since $food equals 'apples', the switch will echo "Eating an apple".
|
||||
// The default case will be run if no other case evaluates to true, like an else statement.
|
||||
$food = 'apples';
|
||||
switch ($food) {
|
||||
case 'apples':
|
||||
echo "Eating an apple\n";
|
||||
break;
|
||||
case 'oranges':
|
||||
echo "Eating an orange\n";
|
||||
break;
|
||||
case 'peaches':
|
||||
echo "Eating a peach\n";
|
||||
break;
|
||||
default:
|
||||
echo "No food, I am hungry\n";
|
||||
}
|
||||
|
||||
// Breaks are a special keyword that tell PHP to stop execution once a case passes.
|
||||
// If you do not use a break, PHP will continue to execute all following cases.
|
||||
// In this switch, both "Drinking water" and "Drinking tea" will be executed since there is no break in the 'water' case.
|
||||
$drink = 'water';
|
||||
switch ($drink) {
|
||||
case 'water':
|
||||
echo "Drinking water\n";
|
||||
case 'tea':
|
||||
echo "Drinking tea\n";
|
||||
break;
|
||||
}
|
||||
|
||||
// PHP also supports single line conditionals called a ternary.
|
||||
// In a ternary, the condition is followed by a question mark before the value that should be returned if the condition is true and then another colon and a value to return if the condition is false.
|
||||
$language = 'english';
|
||||
echo $language == 'spanish' ? "hola\n" : "hello\n";
|
||||
|
||||
// Lastly, there is another form of a ternary that checks if a value is set and then returns the value to the right of two question marks if value is null.
|
||||
echo $IDoNotExist ?? "Variable not set\n";
|
||||
|
||||
// You can also chain multiple checks in a row.
|
||||
$IExist = "Variable exists\n";
|
||||
echo $IDoNotExist ?? $IExist ?? "Neither variable is set\n";
|
46
code/functions.php
Normal file
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
// A function allows you to store code under a name and then execute
|
||||
// that code later.
|
||||
|
||||
// A function always starts with the
|
||||
// function keyword followed by the name with parentheses and then
|
||||
// opening and closing curly braces around the code.
|
||||
function hello_world() {
|
||||
echo "hello world\n";
|
||||
}
|
||||
|
||||
// To call the function, use the function name with parentheses.
|
||||
hello_world();
|
||||
|
||||
// You can set up values to be passed into a function.
|
||||
// To do so, write variables in between the function parentheses.
|
||||
// Each one should be separated by a comma.
|
||||
function greet($firstname, $lastname) {
|
||||
echo "hello $firstname $lastname\n";
|
||||
}
|
||||
|
||||
// Then, you can pass in values when calling a function. In the greet function,
|
||||
// 'John' is assigned to $firstname and 'Smith' is assigned to
|
||||
// $lastname.
|
||||
greet('John', 'Smith');
|
||||
|
||||
// You can also return a value from a function. You can only
|
||||
// return a single value from a function.
|
||||
function capitalize($value) {
|
||||
return strtoupper($value);
|
||||
}
|
||||
|
||||
// When calling a function, it will output the return value which
|
||||
// you can load into a variable.
|
||||
$animal = capitalize('dog');
|
||||
echo "$animal\n";
|
||||
|
||||
// You can also create nameless functions called closures. Closures can be
|
||||
// stored in variables or passed into other functions.
|
||||
$sum = function ($a, $b) {
|
||||
return $a + $b;
|
||||
};
|
||||
|
||||
// You can execute a closure by putting parentheses after the variable.
|
||||
echo $sum(1, 2) . "\n";
|
57
code/loops.php
Normal file
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
// A loop tells PHP to run a block of code more than once.
|
||||
// A classic loop is a while loop.
|
||||
// A "while" loop will continue to run the block of code as long as the value in parentheses is true.
|
||||
$num = 5;
|
||||
while ($num > 0) {
|
||||
echo "While loop $num\n";
|
||||
--$num;
|
||||
}
|
||||
|
||||
// A "do while" loop is similar to a "while" loop except it always runs at least
|
||||
// one iteration. In a classic "while" loop, no iterations may be executed if
|
||||
// the value in parentheses is false. In a "do while", the boolean check
|
||||
// is not done until after the execution of an iteration.
|
||||
$num = 0;
|
||||
do {
|
||||
echo "Do while $num\n";
|
||||
++$num;
|
||||
} while ($num < 5);
|
||||
|
||||
// "for" loops allow you to create a more concise while loop.
|
||||
// Inside the parentheses, the left section creates a variable before the loop
|
||||
// starts, the middle section is the check that is done at the beginning of each loop
|
||||
// and the third section is executed after each loop.
|
||||
for ($i = 0; $i < 10; $i++) {
|
||||
echo "For loop $i\n";
|
||||
}
|
||||
|
||||
// A "foreach" loop allows you to easily loop over an array.
|
||||
// An array is a list of data stored together.
|
||||
// The "as" keyword lets you assign a variable to the value
|
||||
// in the array for the current iteration of the loop.
|
||||
$set = [1, 2, 3, 4, 5];
|
||||
foreach ($set as $num) {
|
||||
echo "Array value $num\n";
|
||||
}
|
||||
|
||||
// In loops, you can use the keyword "break" to stop the loop execution
|
||||
// no matter how many more iterations should run.
|
||||
$values = ['one', 'two', 'three'];
|
||||
foreach ($values as $value) {
|
||||
if ($value === 'two') {
|
||||
break;
|
||||
}
|
||||
echo "Break $value\n";
|
||||
}
|
||||
|
||||
// The "continue" keyword stops executing the current loop iteration,
|
||||
// but then allows the loop to continue with other iterations.
|
||||
$values = ['one', 'skip', 'three'];
|
||||
foreach ($values as $value) {
|
||||
if ($value === 'skip') {
|
||||
continue;
|
||||
}
|
||||
echo "Continue $value\n";
|
||||
}
|
31
code/variables.php
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
// The variable is the basic building block of any programming language.
|
||||
// In PHP, all variables start with a dollar sign.
|
||||
$greeting;
|
||||
|
||||
// To set data in a variable, you put an equals sign after it and some data.
|
||||
$greeting = 'Hello World!';
|
||||
|
||||
// Once you create a variable, you can use it again in other commands and functions.
|
||||
echo $greeting;
|
||||
|
||||
// After the dollar sign, a PHP variable must have an alphabetic character or underscore. Also, variables are case sensitive.
|
||||
$_var = 'I am a variable with an underscore!';
|
||||
$Var = 'I am a variable with a capital letter!';
|
||||
$var = 'I am a new variable';
|
||||
|
||||
// Variables can hold many different types of data, but there are four simple ones you can try now.
|
||||
// An int is a number without a decimal place.
|
||||
// A float is a number with a decimal place.
|
||||
// A boolean can be two values: true or false.
|
||||
// Last, there is a string, a collection of characters.
|
||||
$int = 1;
|
||||
$float = 100.10;
|
||||
$bool = true;
|
||||
$string = 'I am a string';
|
||||
|
||||
// In other programming languages, you have to write what type of data the variable will contain.
|
||||
// PHP keeps it simple by allowing you to put any type of data in a variable, including already used variables.
|
||||
$number = 1;
|
||||
$number = 'one';
|
24
composer.json
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"name": "restoreddev/php-apprentice",
|
||||
"description": "A site for learning PHP",
|
||||
"require": {
|
||||
"php": "^7.1.3",
|
||||
"symfony/console": "^4.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^7.3"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Apprentice\\": "src/"
|
||||
},
|
||||
"files": [
|
||||
"src/util/functions.php"
|
||||
]
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"Test\\": "test/"
|
||||
}
|
||||
}
|
||||
}
|
1553
composer.lock
generated
Normal file
83
config.php
Normal file
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
|
||||
use Apprentice\Page;
|
||||
|
||||
return [
|
||||
'icon_dir' => __DIR__ . '/assets/icons',
|
||||
'code_dir' => __DIR__ . '/code',
|
||||
'templates_dir' => __DIR__ . '/assets/templates',
|
||||
'output_dir' => __DIR__ . '/docs',
|
||||
'pages' => [
|
||||
Page::create('index', 'index.phtml'),
|
||||
Page::create('credits', 'credits.phtml'),
|
||||
Page::create('basics', null, 'basics.php', [
|
||||
'title' => 'Basics',
|
||||
'subtitle' => 'Getting started',
|
||||
'description' => 'Let us get started with the basics.',
|
||||
'next' => 'variables',
|
||||
]),
|
||||
Page::create('variables', null, 'variables.php', [
|
||||
'title' => 'Variables',
|
||||
'subtitle' => 'The building blocks of PHP',
|
||||
'description' => '',
|
||||
'previous' => 'basics',
|
||||
'next' => 'arithmetic',
|
||||
]),
|
||||
Page::create('arithmetic', null, 'arithmetic.php', [
|
||||
'title' => 'Arithmetic',
|
||||
'subtitle' => 'Doing math like a pro',
|
||||
'description' => '',
|
||||
'previous' => 'variables',
|
||||
'next' => 'comparisons',
|
||||
]),
|
||||
Page::create('comparisons', null, 'comparisons.php', [
|
||||
'title' => 'Comparisons',
|
||||
'subtitle' => 'Equality checking',
|
||||
'description' => '',
|
||||
'previous' => 'arithmetic',
|
||||
'next' => 'boolean-logic',
|
||||
]),
|
||||
Page::create('boolean-logic', null, 'boolean-logic.php', [
|
||||
'title' => 'Boolean Logic',
|
||||
'subtitle' => 'Is it a yes or a no?',
|
||||
'description' => '',
|
||||
'previous' => 'comparisons',
|
||||
'next' => 'conditionals',
|
||||
]),
|
||||
Page::create('conditionals', null, 'conditionals.php', [
|
||||
'title' => 'Conditionals',
|
||||
'subtitle' => 'Checking the if before the what',
|
||||
'description' => '',
|
||||
'previous' => 'boolean-logic',
|
||||
'next' => 'loops',
|
||||
]),
|
||||
Page::create('loops', null, 'loops.php', [
|
||||
'title' => 'Loops',
|
||||
'subtitle' => 'Increase your repetitions',
|
||||
'description' => '',
|
||||
'previous' => 'conditionals',
|
||||
'next' => 'arrays',
|
||||
]),
|
||||
Page::create('arrays', null, 'arrays.php', [
|
||||
'title' => 'Arrays',
|
||||
'subtitle' => 'Time to make a list',
|
||||
'description' => '',
|
||||
'previous' => 'loops',
|
||||
'next' => 'functions',
|
||||
]),
|
||||
Page::create('functions', null, 'functions.php', [
|
||||
'title' => 'Functions',
|
||||
'subtitle' => 'Reusable code',
|
||||
'description' => '',
|
||||
'previous' => 'arrays',
|
||||
'next' => 'classes',
|
||||
]),
|
||||
Page::create('classes', null, 'classes.php', [
|
||||
'title' => 'Classes',
|
||||
'subtitle' => 'Object-oriented programming',
|
||||
'description' => '',
|
||||
'previous' => 'functions',
|
||||
'next' => '',
|
||||
]),
|
||||
],
|
||||
];
|
84
docs/arithmetic.html
Normal file
@@ -0,0 +1,84 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<title>Arithmetic</title>
|
||||
<meta name="description" content="">
|
||||
|
||||
<link rel="stylesheet" href="/css/site.css">
|
||||
<link rel="icon" href="/favicon-32.png">
|
||||
<script src="/js/site.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div class="menu">
|
||||
<button class="menu-button" title="Open Menu">
|
||||
<div class="icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M0 3h20v2H0V3zm0 6h20v2H0V9zm0 6h20v2H0v-2z"/></svg></div>
|
||||
Menu
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="container center">
|
||||
<h1>Arithmetic</h1>
|
||||
<h3 class="subtitle">Doing math like a pro</h3>
|
||||
<div class="grid-code"><div class="doc"></div><div class="code"><pre><code class="language-php"><?php
|
||||
|
||||
</code></pre></div><div class="doc">Now that we know how to create variables, let's look at doing some math.</div><div class="code"><pre><code class="language-php">$a = 1;
|
||||
$b = 2;
|
||||
|
||||
</code></pre></div><div class="doc">To add two values, use the plus symbol.</div><div class="code"><pre><code class="language-php">$c = $a + $b;
|
||||
|
||||
</code></pre></div><div class="doc">To subtract, use the minus symbol.</div><div class="code"><pre><code class="language-php">$c = $b - $a;
|
||||
|
||||
</code></pre></div><div class="doc">To multiply two values, use an asterisk.</div><div class="code"><pre><code class="language-php">echo $a * $b;
|
||||
|
||||
</code></pre></div><div class="doc">To divide values, use a forward slash.</div><div class="code"><pre><code class="language-php">echo $b / $a;
|
||||
|
||||
</code></pre></div><div class="doc">PHP uses the percent symbol for calculating the modulus of two numbers. The modulus is calculated by dividing two numbers and returning the remainder of the result. So, in this example, the value of $modulo will be 0.</div><div class="code"><pre><code class="language-php">$modulo = 10 % 5;
|
||||
|
||||
</code></pre></div><div class="doc">You can also use double asterisks to calculate a number to the power of another number. The following statement will print 25.</div><div class="code"><pre><code class="language-php">echo 5 ** 2;
|
||||
</code></pre></div></div>
|
||||
<div class="clearfix"></div>
|
||||
<div class="navigate-links">
|
||||
<a href="/variables.html" title="Previous">
|
||||
<div class="icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M10 20a10 10 0 1 1 0-20 10 10 0 0 1 0 20zm8-10a8 8 0 1 0-16 0 8 8 0 0 0 16 0zM7.46 9.3L11 5.75l1.41 1.41L9.6 10l2.82 2.83L11 14.24 6.76 10l.7-.7z"/></svg></div>
|
||||
Previous
|
||||
</a>
|
||||
<a href="/comparisons.html" title="Next">
|
||||
Next
|
||||
<div class="icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M10 0a10 10 0 1 1 0 20 10 10 0 0 1 0-20zM2 10a8 8 0 1 0 16 0 8 8 0 0 0-16 0zm10.54.7L9 14.25l-1.41-1.41L10.4 10 7.6 7.17 9 5.76 13.24 10l-.7.7z"/></svg></div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal closed">
|
||||
<div class="modal-content">
|
||||
<button class="modal-button right" title="Close">
|
||||
<div class="icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M2.93 17.07A10 10 0 1 1 17.07 2.93 10 10 0 0 1 2.93 17.07zm1.41-1.41A8 8 0 1 0 15.66 4.34 8 8 0 0 0 4.34 15.66zm9.9-8.49L11.41 10l2.83 2.83-1.41 1.41L10 11.41l-2.83 2.83-1.41-1.41L8.59 10 5.76 7.17l1.41-1.41L10 8.59l2.83-2.83 1.41 1.41z"/></svg></div>
|
||||
</button>
|
||||
<div class="table-of-contents">
|
||||
<h4>Table of Contents</h4>
|
||||
<a href="/index.html">Preface</a>
|
||||
<ol>
|
||||
<li><a href="/basics.html">Basics</a></li>
|
||||
<li><a href="/variables.html">Variables</a></li>
|
||||
<li><a href="/arithmetic.html">Arithmetic</a></li>
|
||||
<li><a href="/comparisons.html">Comparisons</a></li>
|
||||
<li><a href="/boolean-logic.html">Boolean Logic</a></li>
|
||||
<li><a href="/conditionals.html">Conditionals</a></li>
|
||||
<li><a href="/loops.html">Loops</a></li>
|
||||
<li><a href="/arrays.html">Arrays</a></li>
|
||||
<li><a href="/functions.html">Functions</a></li>
|
||||
<li><a href="/classes.html">Classes</a></li>
|
||||
</ol>
|
||||
<a href="/credits.html">Credits</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
80
docs/arrays.html
Normal file
@@ -0,0 +1,80 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<title>Arrays</title>
|
||||
<meta name="description" content="">
|
||||
|
||||
<link rel="stylesheet" href="/css/site.css">
|
||||
<link rel="icon" href="/favicon-32.png">
|
||||
<script src="/js/site.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div class="menu">
|
||||
<button class="menu-button" title="Open Menu">
|
||||
<div class="icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M0 3h20v2H0V3zm0 6h20v2H0V9zm0 6h20v2H0v-2z"/></svg></div>
|
||||
Menu
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="container center">
|
||||
<h1>Arrays</h1>
|
||||
<h3 class="subtitle">Time to make a list</h3>
|
||||
<div class="grid-code"><div class="doc"></div><div class="code"><pre><code class="language-php"><?php
|
||||
|
||||
</code></pre></div><div class="doc">There are two ways to create an array. First, you can use the array construct to pass in values separated by commas and it will return an array.</div><div class="code"><pre><code class="language-php">$taskList = array('grocery store', 'change car oil');
|
||||
|
||||
</code></pre></div><div class="doc">Second, you can surround the list in square brackets. This style is the most common and recommended form of creating an array.</div><div class="code"><pre><code class="language-php">$groceryList = ['bread', 'milk', 'eggs'];
|
||||
|
||||
</code></pre></div><div class="doc">PHP will automatically assign index keys for each value in an array starting with 0. So, to access a value in an array you will pass the key number into brackets after the variable name.</div><div class="code"><pre><code class="language-php">echo $groceryList[0] . "\n";
|
||||
echo $groceryList[1] . "\n";
|
||||
|
||||
</code></pre></div><div class="doc">You can also assign keys in an array using numbers or strings. It is very common to create an array with string keys. The pattern is called an associative array or a map.</div><div class="code"><pre><code class="language-php">$car = ['make' => 'Toyota', 'model' => 'Camry'];
|
||||
|
||||
</code></pre></div><div class="doc">To access the value in an associative array, just use the string key in brackets after the variable name.</div><div class="code"><pre><code class="language-php">echo $car['model'] . "\n";
|
||||
</code></pre></div></div>
|
||||
<div class="clearfix"></div>
|
||||
<div class="navigate-links">
|
||||
<a href="/loops.html" title="Previous">
|
||||
<div class="icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M10 20a10 10 0 1 1 0-20 10 10 0 0 1 0 20zm8-10a8 8 0 1 0-16 0 8 8 0 0 0 16 0zM7.46 9.3L11 5.75l1.41 1.41L9.6 10l2.82 2.83L11 14.24 6.76 10l.7-.7z"/></svg></div>
|
||||
Previous
|
||||
</a>
|
||||
<a href="/functions.html" title="Next">
|
||||
Next
|
||||
<div class="icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M10 0a10 10 0 1 1 0 20 10 10 0 0 1 0-20zM2 10a8 8 0 1 0 16 0 8 8 0 0 0-16 0zm10.54.7L9 14.25l-1.41-1.41L10.4 10 7.6 7.17 9 5.76 13.24 10l-.7.7z"/></svg></div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal closed">
|
||||
<div class="modal-content">
|
||||
<button class="modal-button right" title="Close">
|
||||
<div class="icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M2.93 17.07A10 10 0 1 1 17.07 2.93 10 10 0 0 1 2.93 17.07zm1.41-1.41A8 8 0 1 0 15.66 4.34 8 8 0 0 0 4.34 15.66zm9.9-8.49L11.41 10l2.83 2.83-1.41 1.41L10 11.41l-2.83 2.83-1.41-1.41L8.59 10 5.76 7.17l1.41-1.41L10 8.59l2.83-2.83 1.41 1.41z"/></svg></div>
|
||||
</button>
|
||||
<div class="table-of-contents">
|
||||
<h4>Table of Contents</h4>
|
||||
<a href="/index.html">Preface</a>
|
||||
<ol>
|
||||
<li><a href="/basics.html">Basics</a></li>
|
||||
<li><a href="/variables.html">Variables</a></li>
|
||||
<li><a href="/arithmetic.html">Arithmetic</a></li>
|
||||
<li><a href="/comparisons.html">Comparisons</a></li>
|
||||
<li><a href="/boolean-logic.html">Boolean Logic</a></li>
|
||||
<li><a href="/conditionals.html">Conditionals</a></li>
|
||||
<li><a href="/loops.html">Loops</a></li>
|
||||
<li><a href="/arrays.html">Arrays</a></li>
|
||||
<li><a href="/functions.html">Functions</a></li>
|
||||
<li><a href="/classes.html">Classes</a></li>
|
||||
</ol>
|
||||
<a href="/credits.html">Credits</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
78
docs/basics.html
Normal file
@@ -0,0 +1,78 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<title>Basics</title>
|
||||
<meta name="description" content="Let us get started with the basics.">
|
||||
|
||||
<link rel="stylesheet" href="/css/site.css">
|
||||
<link rel="icon" href="/favicon-32.png">
|
||||
<script src="/js/site.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div class="menu">
|
||||
<button class="menu-button" title="Open Menu">
|
||||
<div class="icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M0 3h20v2H0V3zm0 6h20v2H0V9zm0 6h20v2H0v-2z"/></svg></div>
|
||||
Menu
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="container center">
|
||||
<h1>Basics</h1>
|
||||
<h3 class="subtitle">Getting started</h3>
|
||||
<div class="grid-code"><div class="doc"></div><div class="code"><pre><code class="language-php"><?php
|
||||
|
||||
</code></pre></div><div class="doc">In the tradition of our ancestors, let's start with a hello world program. All PHP files must start with a <?php tag unless it is for a html template. (We will learn about html templates later.)</div><div class="code"><pre><code class="language-php">echo "Hello World!\n";
|
||||
|
||||
</code></pre></div><div class="doc">There is a lot going on in this statement so let's work through it.</div><div class="code"><pre><code class="language-php">
|
||||
</code></pre></div><div class="doc">First, the echo keyword tells PHP to output some text.</div><div class="code"><pre><code class="language-php">echo 'I am some text';
|
||||
|
||||
</code></pre></div><div class="doc">Second, PHP stores text in strings.</div><div class="code"><pre><code class="language-php">
|
||||
</code></pre></div><div class="doc">To write a string, you surround letters with single or double quotes. The difference between single quoted strings and double quoted strings is that double quoted strings can hold special characters like \n which tells PHP to start a new line.</div><div class="code"><pre><code class="language-php">'I am a string';
|
||||
"\nI am a string on a new line";
|
||||
|
||||
</code></pre></div><div class="doc">Third, all lines of code in PHP must end in a semi-colon.</div><div class="code"><pre><code class="language-php">echo "No semi-colon is a no-no\n";
|
||||
|
||||
</code></pre></div><div class="doc">Using semi-colons means we can write multiple statements on one line.</div><div class="code"><pre><code class="language-php">echo 'Hello'; echo " World\n";
|
||||
</code></pre></div></div>
|
||||
<div class="clearfix"></div>
|
||||
<div class="navigate-links">
|
||||
<a href="/variables.html" title="Next">
|
||||
Next
|
||||
<div class="icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M10 0a10 10 0 1 1 0 20 10 10 0 0 1 0-20zM2 10a8 8 0 1 0 16 0 8 8 0 0 0-16 0zm10.54.7L9 14.25l-1.41-1.41L10.4 10 7.6 7.17 9 5.76 13.24 10l-.7.7z"/></svg></div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal closed">
|
||||
<div class="modal-content">
|
||||
<button class="modal-button right" title="Close">
|
||||
<div class="icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M2.93 17.07A10 10 0 1 1 17.07 2.93 10 10 0 0 1 2.93 17.07zm1.41-1.41A8 8 0 1 0 15.66 4.34 8 8 0 0 0 4.34 15.66zm9.9-8.49L11.41 10l2.83 2.83-1.41 1.41L10 11.41l-2.83 2.83-1.41-1.41L8.59 10 5.76 7.17l1.41-1.41L10 8.59l2.83-2.83 1.41 1.41z"/></svg></div>
|
||||
</button>
|
||||
<div class="table-of-contents">
|
||||
<h4>Table of Contents</h4>
|
||||
<a href="/index.html">Preface</a>
|
||||
<ol>
|
||||
<li><a href="/basics.html">Basics</a></li>
|
||||
<li><a href="/variables.html">Variables</a></li>
|
||||
<li><a href="/arithmetic.html">Arithmetic</a></li>
|
||||
<li><a href="/comparisons.html">Comparisons</a></li>
|
||||
<li><a href="/boolean-logic.html">Boolean Logic</a></li>
|
||||
<li><a href="/conditionals.html">Conditionals</a></li>
|
||||
<li><a href="/loops.html">Loops</a></li>
|
||||
<li><a href="/arrays.html">Arrays</a></li>
|
||||
<li><a href="/functions.html">Functions</a></li>
|
||||
<li><a href="/classes.html">Classes</a></li>
|
||||
</ol>
|
||||
<a href="/credits.html">Credits</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
90
docs/boolean-logic.html
Normal file
@@ -0,0 +1,90 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<title>Boolean Logic</title>
|
||||
<meta name="description" content="">
|
||||
|
||||
<link rel="stylesheet" href="/css/site.css">
|
||||
<link rel="icon" href="/favicon-32.png">
|
||||
<script src="/js/site.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div class="menu">
|
||||
<button class="menu-button" title="Open Menu">
|
||||
<div class="icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M0 3h20v2H0V3zm0 6h20v2H0V9zm0 6h20v2H0v-2z"/></svg></div>
|
||||
Menu
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="container center">
|
||||
<h1>Boolean Logic</h1>
|
||||
<h3 class="subtitle">Is it a yes or a no?</h3>
|
||||
<div class="grid-code"><div class="doc"></div><div class="code"><pre><code class="language-php"><?php
|
||||
|
||||
</code></pre></div><div class="doc">Boolean logic is used to combine booleans to return another boolean.</div><div class="code"><pre><code class="language-php">
|
||||
</code></pre></div><div class="doc">Using double ampersands tells PHP to check if both values are true. If so, it will return true. If not, it will return false.</div><div class="code"><pre><code class="language-php">$a = true;
|
||||
$b = true;
|
||||
$c = false;
|
||||
|
||||
</code></pre></div><div class="doc">Returns true.</div><div class="code"><pre><code class="language-php">$a && $b;
|
||||
</code></pre></div><div class="doc">Returns false.</div><div class="code"><pre><code class="language-php">$a && $c;
|
||||
|
||||
</code></pre></div><div class="doc">Using two pipe characters checks if either value is true. Then, it will return true. If both values are false, the PHP returns false.</div><div class="code"><pre><code class="language-php">$a = true;
|
||||
$b = false;
|
||||
$c = false;
|
||||
$d = true;
|
||||
|
||||
</code></pre></div><div class="doc">Returns true.</div><div class="code"><pre><code class="language-php">$a || $b;
|
||||
</code></pre></div><div class="doc">Returns false.</div><div class="code"><pre><code class="language-php">$b || $c;
|
||||
</code></pre></div><div class="doc">Returns true.</div><div class="code"><pre><code class="language-php">$a || $d;
|
||||
|
||||
</code></pre></div><div class="doc">Using an exclamation point returns the value flipped.</div><div class="code"><pre><code class="language-php">$d = true;
|
||||
|
||||
</code></pre></div><div class="doc">Outputs false.</div><div class="code"><pre><code class="language-php">echo !$d;
|
||||
</code></pre></div></div>
|
||||
<div class="clearfix"></div>
|
||||
<div class="navigate-links">
|
||||
<a href="/comparisons.html" title="Previous">
|
||||
<div class="icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M10 20a10 10 0 1 1 0-20 10 10 0 0 1 0 20zm8-10a8 8 0 1 0-16 0 8 8 0 0 0 16 0zM7.46 9.3L11 5.75l1.41 1.41L9.6 10l2.82 2.83L11 14.24 6.76 10l.7-.7z"/></svg></div>
|
||||
Previous
|
||||
</a>
|
||||
<a href="/conditionals.html" title="Next">
|
||||
Next
|
||||
<div class="icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M10 0a10 10 0 1 1 0 20 10 10 0 0 1 0-20zM2 10a8 8 0 1 0 16 0 8 8 0 0 0-16 0zm10.54.7L9 14.25l-1.41-1.41L10.4 10 7.6 7.17 9 5.76 13.24 10l-.7.7z"/></svg></div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal closed">
|
||||
<div class="modal-content">
|
||||
<button class="modal-button right" title="Close">
|
||||
<div class="icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M2.93 17.07A10 10 0 1 1 17.07 2.93 10 10 0 0 1 2.93 17.07zm1.41-1.41A8 8 0 1 0 15.66 4.34 8 8 0 0 0 4.34 15.66zm9.9-8.49L11.41 10l2.83 2.83-1.41 1.41L10 11.41l-2.83 2.83-1.41-1.41L8.59 10 5.76 7.17l1.41-1.41L10 8.59l2.83-2.83 1.41 1.41z"/></svg></div>
|
||||
</button>
|
||||
<div class="table-of-contents">
|
||||
<h4>Table of Contents</h4>
|
||||
<a href="/index.html">Preface</a>
|
||||
<ol>
|
||||
<li><a href="/basics.html">Basics</a></li>
|
||||
<li><a href="/variables.html">Variables</a></li>
|
||||
<li><a href="/arithmetic.html">Arithmetic</a></li>
|
||||
<li><a href="/comparisons.html">Comparisons</a></li>
|
||||
<li><a href="/boolean-logic.html">Boolean Logic</a></li>
|
||||
<li><a href="/conditionals.html">Conditionals</a></li>
|
||||
<li><a href="/loops.html">Loops</a></li>
|
||||
<li><a href="/arrays.html">Arrays</a></li>
|
||||
<li><a href="/functions.html">Functions</a></li>
|
||||
<li><a href="/classes.html">Classes</a></li>
|
||||
</ol>
|
||||
<a href="/credits.html">Credits</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
94
docs/classes.html
Normal file
@@ -0,0 +1,94 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<title>Classes</title>
|
||||
<meta name="description" content="">
|
||||
|
||||
<link rel="stylesheet" href="/css/site.css">
|
||||
<link rel="icon" href="/favicon-32.png">
|
||||
<script src="/js/site.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div class="menu">
|
||||
<button class="menu-button" title="Open Menu">
|
||||
<div class="icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M0 3h20v2H0V3zm0 6h20v2H0V9zm0 6h20v2H0v-2z"/></svg></div>
|
||||
Menu
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="container center">
|
||||
<h1>Classes</h1>
|
||||
<h3 class="subtitle">Object-oriented programming</h3>
|
||||
<div class="grid-code"><div class="doc"></div><div class="code"><pre><code class="language-php"><?php
|
||||
|
||||
</code></pre></div><div class="doc">Classes allow you to define your own data types. All classes start with the class keyword followed by the name of the class and opening and closing curly braces.</div><div class="code"><pre><code class="language-php">class Car
|
||||
{
|
||||
}
|
||||
|
||||
</code></pre></div><div class="doc">To create an instance of a class, you use the "new" keyword in front of the class name with parentheses.</div><div class="code"><pre><code class="language-php">$car = new Car();
|
||||
|
||||
</code></pre></div><div class="doc">A class can define attributes and methods. An attribute is a piece of data stored on the class instance. You can define an attribute by adding the word "public" and a variable name inside the class definition.</div><div class="code"><pre><code class="language-php">class Bicycle
|
||||
{
|
||||
public $color;
|
||||
}
|
||||
|
||||
</code></pre></div><div class="doc">Then, when you create an instance of the class, you can set and use the color attribute on the bicycle using "->".</div><div class="code"><pre><code class="language-php">$bike = new Bicycle();
|
||||
$bike->color = 'Blue';
|
||||
echo $bike->color . "\n";
|
||||
|
||||
</code></pre></div><div class="doc">A method is a function attached to the class. You can add a method to a class by using the "public" keyword followed by the function. A method can access the attributes and methods of the instance using the "$this" variable.</div><div class="code"><pre><code class="language-php">class Tricycle
|
||||
{
|
||||
public $color;
|
||||
|
||||
public function echoColor()
|
||||
{
|
||||
echo $this->color . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
$bike = new Tricycle();
|
||||
$bike->color = 'Red';
|
||||
$bike->echoColor();
|
||||
</code></pre></div></div>
|
||||
<div class="clearfix"></div>
|
||||
<div class="navigate-links">
|
||||
<a href="/functions.html" title="Previous">
|
||||
<div class="icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M10 20a10 10 0 1 1 0-20 10 10 0 0 1 0 20zm8-10a8 8 0 1 0-16 0 8 8 0 0 0 16 0zM7.46 9.3L11 5.75l1.41 1.41L9.6 10l2.82 2.83L11 14.24 6.76 10l.7-.7z"/></svg></div>
|
||||
Previous
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal closed">
|
||||
<div class="modal-content">
|
||||
<button class="modal-button right" title="Close">
|
||||
<div class="icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M2.93 17.07A10 10 0 1 1 17.07 2.93 10 10 0 0 1 2.93 17.07zm1.41-1.41A8 8 0 1 0 15.66 4.34 8 8 0 0 0 4.34 15.66zm9.9-8.49L11.41 10l2.83 2.83-1.41 1.41L10 11.41l-2.83 2.83-1.41-1.41L8.59 10 5.76 7.17l1.41-1.41L10 8.59l2.83-2.83 1.41 1.41z"/></svg></div>
|
||||
</button>
|
||||
<div class="table-of-contents">
|
||||
<h4>Table of Contents</h4>
|
||||
<a href="/index.html">Preface</a>
|
||||
<ol>
|
||||
<li><a href="/basics.html">Basics</a></li>
|
||||
<li><a href="/variables.html">Variables</a></li>
|
||||
<li><a href="/arithmetic.html">Arithmetic</a></li>
|
||||
<li><a href="/comparisons.html">Comparisons</a></li>
|
||||
<li><a href="/boolean-logic.html">Boolean Logic</a></li>
|
||||
<li><a href="/conditionals.html">Conditionals</a></li>
|
||||
<li><a href="/loops.html">Loops</a></li>
|
||||
<li><a href="/arrays.html">Arrays</a></li>
|
||||
<li><a href="/functions.html">Functions</a></li>
|
||||
<li><a href="/classes.html">Classes</a></li>
|
||||
</ol>
|
||||
<a href="/credits.html">Credits</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
91
docs/comparisons.html
Normal file
@@ -0,0 +1,91 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<title>Comparisons</title>
|
||||
<meta name="description" content="">
|
||||
|
||||
<link rel="stylesheet" href="/css/site.css">
|
||||
<link rel="icon" href="/favicon-32.png">
|
||||
<script src="/js/site.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div class="menu">
|
||||
<button class="menu-button" title="Open Menu">
|
||||
<div class="icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M0 3h20v2H0V3zm0 6h20v2H0V9zm0 6h20v2H0v-2z"/></svg></div>
|
||||
Menu
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="container center">
|
||||
<h1>Comparisons</h1>
|
||||
<h3 class="subtitle">Equality checking</h3>
|
||||
<div class="grid-code"><div class="doc"></div><div class="code"><pre><code class="language-php"><?php
|
||||
|
||||
</code></pre></div><div class="doc">A boolean is a value that is always 0 or 1, yes or no, on or off. In PHP, a boolean is represented by the words true and false. While programming, you will often want to know if something is true or false.</div><div class="code"><pre><code class="language-php">$a = true;
|
||||
$b = false;
|
||||
|
||||
</code></pre></div><div class="doc">There are many constructs and functions that will return a boolean. To start, let's look at comparisons.</div><div class="code"><pre><code class="language-php">$one = 1;
|
||||
$two = 2;
|
||||
|
||||
</code></pre></div><div class="doc">Double equals checks if two values are equal. This statement will return false.</div><div class="code"><pre><code class="language-php">$one == $two;
|
||||
|
||||
</code></pre></div><div class="doc">An exclamation point and equal sign check if two values are not equal. This statement will return true.</div><div class="code"><pre><code class="language-php">$one != $two;
|
||||
|
||||
</code></pre></div><div class="doc">You can use greater than and less than symbols to check for comparisons too. This statement will return false.</div><div class="code"><pre><code class="language-php">$one > $two;
|
||||
|
||||
</code></pre></div><div class="doc">This statement will return true.</div><div class="code"><pre><code class="language-php">$one < $two;
|
||||
|
||||
</code></pre></div><div class="doc">If you combine a greater than or less than symbol with an equal, it will check if the value is greater or less than or equal to another value.</div><div class="code"><pre><code class="language-php">$one <= $two;
|
||||
$one >= $two;
|
||||
|
||||
</code></pre></div><div class="doc">You can also check that two values are equal and of the same type by using three equal signs.</div><div class="code"><pre><code class="language-php">
|
||||
</code></pre></div><div class="doc">This returns true.</div><div class="code"><pre><code class="language-php">1 == '1';
|
||||
|
||||
</code></pre></div><div class="doc">This returns false.</div><div class="code"><pre><code class="language-php">1 === '1';
|
||||
</code></pre></div></div>
|
||||
<div class="clearfix"></div>
|
||||
<div class="navigate-links">
|
||||
<a href="/arithmetic.html" title="Previous">
|
||||
<div class="icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M10 20a10 10 0 1 1 0-20 10 10 0 0 1 0 20zm8-10a8 8 0 1 0-16 0 8 8 0 0 0 16 0zM7.46 9.3L11 5.75l1.41 1.41L9.6 10l2.82 2.83L11 14.24 6.76 10l.7-.7z"/></svg></div>
|
||||
Previous
|
||||
</a>
|
||||
<a href="/boolean-logic.html" title="Next">
|
||||
Next
|
||||
<div class="icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M10 0a10 10 0 1 1 0 20 10 10 0 0 1 0-20zM2 10a8 8 0 1 0 16 0 8 8 0 0 0-16 0zm10.54.7L9 14.25l-1.41-1.41L10.4 10 7.6 7.17 9 5.76 13.24 10l-.7.7z"/></svg></div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal closed">
|
||||
<div class="modal-content">
|
||||
<button class="modal-button right" title="Close">
|
||||
<div class="icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M2.93 17.07A10 10 0 1 1 17.07 2.93 10 10 0 0 1 2.93 17.07zm1.41-1.41A8 8 0 1 0 15.66 4.34 8 8 0 0 0 4.34 15.66zm9.9-8.49L11.41 10l2.83 2.83-1.41 1.41L10 11.41l-2.83 2.83-1.41-1.41L8.59 10 5.76 7.17l1.41-1.41L10 8.59l2.83-2.83 1.41 1.41z"/></svg></div>
|
||||
</button>
|
||||
<div class="table-of-contents">
|
||||
<h4>Table of Contents</h4>
|
||||
<a href="/index.html">Preface</a>
|
||||
<ol>
|
||||
<li><a href="/basics.html">Basics</a></li>
|
||||
<li><a href="/variables.html">Variables</a></li>
|
||||
<li><a href="/arithmetic.html">Arithmetic</a></li>
|
||||
<li><a href="/comparisons.html">Comparisons</a></li>
|
||||
<li><a href="/boolean-logic.html">Boolean Logic</a></li>
|
||||
<li><a href="/conditionals.html">Conditionals</a></li>
|
||||
<li><a href="/loops.html">Loops</a></li>
|
||||
<li><a href="/arrays.html">Arrays</a></li>
|
||||
<li><a href="/functions.html">Functions</a></li>
|
||||
<li><a href="/classes.html">Classes</a></li>
|
||||
</ol>
|
||||
<a href="/credits.html">Credits</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
119
docs/conditionals.html
Normal file
@@ -0,0 +1,119 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<title>Conditionals</title>
|
||||
<meta name="description" content="">
|
||||
|
||||
<link rel="stylesheet" href="/css/site.css">
|
||||
<link rel="icon" href="/favicon-32.png">
|
||||
<script src="/js/site.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div class="menu">
|
||||
<button class="menu-button" title="Open Menu">
|
||||
<div class="icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M0 3h20v2H0V3zm0 6h20v2H0V9zm0 6h20v2H0v-2z"/></svg></div>
|
||||
Menu
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="container center">
|
||||
<h1>Conditionals</h1>
|
||||
<h3 class="subtitle">Checking the if before the what</h3>
|
||||
<div class="grid-code"><div class="doc"></div><div class="code"><pre><code class="language-php"><?php
|
||||
|
||||
</code></pre></div><div class="doc">When writing code, there will be times when you need to perform actions only under certain circumstances. There are several ways to control execution in PHP. We will start with an if statement.</div><div class="code"><pre><code class="language-php">$animal = 'cow';
|
||||
if ($animal == 'cow') {
|
||||
echo "Moooooo.....\n";
|
||||
}
|
||||
|
||||
</code></pre></div><div class="doc">All conditionals check to see if a statement evaluates to true or false. In the case above, since $animal equals 'cow', the statement returns true and the contents of the if statement are executed.</div><div class="code"><pre><code class="language-php">
|
||||
|
||||
</code></pre></div><div class="doc">An if statement can have multiple conditions chained together. If the first if statement returns false, then PHP will check each elseif. If none of the checks return true, then the else block will be executed.</div><div class="code"><pre><code class="language-php">$animal = 'bird';
|
||||
if ($animal == 'dog') {
|
||||
echo "Woof! 🐶\n";
|
||||
} elseif ($animal == 'cat') {
|
||||
echo "Meow!? 🐱\n";
|
||||
} elseif ($animal == 'bird') {
|
||||
echo "Chirp! 🐦\n";
|
||||
} else {
|
||||
echo "I am not a dog, cat or bird\n";
|
||||
}
|
||||
|
||||
</code></pre></div><div class="doc">An alternative to the if statement is the switch. A switch statement has multiple cases to check if the value in parentheses equals something. In this statement, since $food equals 'apples', the switch will echo "Eating an apple". The default case will be run if no other case evaluates to true, like an else statement.</div><div class="code"><pre><code class="language-php">$food = 'apples';
|
||||
switch ($food) {
|
||||
case 'apples':
|
||||
echo "Eating an apple\n";
|
||||
break;
|
||||
case 'oranges':
|
||||
echo "Eating an orange\n";
|
||||
break;
|
||||
case 'peaches':
|
||||
echo "Eating a peach\n";
|
||||
break;
|
||||
default:
|
||||
echo "No food, I am hungry\n";
|
||||
}
|
||||
|
||||
</code></pre></div><div class="doc">Breaks are a special keyword that tell PHP to stop execution once a case passes. If you do not use a break, PHP will continue to execute all following cases. In this switch, both "Drinking water" and "Drinking tea" will be executed since there is no break in the 'water' case.</div><div class="code"><pre><code class="language-php">$drink = 'water';
|
||||
switch ($drink) {
|
||||
case 'water':
|
||||
echo "Drinking water\n";
|
||||
case 'tea':
|
||||
echo "Drinking tea\n";
|
||||
break;
|
||||
}
|
||||
|
||||
</code></pre></div><div class="doc">PHP also supports single line conditionals called a ternary. In a ternary, the condition is followed by a question mark before the value that should be returned if the condition is true and then another colon and a value to return if the condition is false.</div><div class="code"><pre><code class="language-php">$language = 'english';
|
||||
echo $language == 'spanish' ? "hola\n" : "hello\n";
|
||||
|
||||
</code></pre></div><div class="doc">Lastly, there is another form of a ternary that checks if a value is set and then returns the value to the right of two question marks if value is null.</div><div class="code"><pre><code class="language-php">echo $IDoNotExist ?? "Variable not set\n";
|
||||
|
||||
</code></pre></div><div class="doc">You can also chain multiple checks in a row.</div><div class="code"><pre><code class="language-php">$IExist = "Variable exists\n";
|
||||
echo $IDoNotExist ?? $IExist ?? "Neither variable is set\n";
|
||||
</code></pre></div></div>
|
||||
<div class="clearfix"></div>
|
||||
<div class="navigate-links">
|
||||
<a href="/boolean-logic.html" title="Previous">
|
||||
<div class="icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M10 20a10 10 0 1 1 0-20 10 10 0 0 1 0 20zm8-10a8 8 0 1 0-16 0 8 8 0 0 0 16 0zM7.46 9.3L11 5.75l1.41 1.41L9.6 10l2.82 2.83L11 14.24 6.76 10l.7-.7z"/></svg></div>
|
||||
Previous
|
||||
</a>
|
||||
<a href="/loops.html" title="Next">
|
||||
Next
|
||||
<div class="icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M10 0a10 10 0 1 1 0 20 10 10 0 0 1 0-20zM2 10a8 8 0 1 0 16 0 8 8 0 0 0-16 0zm10.54.7L9 14.25l-1.41-1.41L10.4 10 7.6 7.17 9 5.76 13.24 10l-.7.7z"/></svg></div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal closed">
|
||||
<div class="modal-content">
|
||||
<button class="modal-button right" title="Close">
|
||||
<div class="icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M2.93 17.07A10 10 0 1 1 17.07 2.93 10 10 0 0 1 2.93 17.07zm1.41-1.41A8 8 0 1 0 15.66 4.34 8 8 0 0 0 4.34 15.66zm9.9-8.49L11.41 10l2.83 2.83-1.41 1.41L10 11.41l-2.83 2.83-1.41-1.41L8.59 10 5.76 7.17l1.41-1.41L10 8.59l2.83-2.83 1.41 1.41z"/></svg></div>
|
||||
</button>
|
||||
<div class="table-of-contents">
|
||||
<h4>Table of Contents</h4>
|
||||
<a href="/index.html">Preface</a>
|
||||
<ol>
|
||||
<li><a href="/basics.html">Basics</a></li>
|
||||
<li><a href="/variables.html">Variables</a></li>
|
||||
<li><a href="/arithmetic.html">Arithmetic</a></li>
|
||||
<li><a href="/comparisons.html">Comparisons</a></li>
|
||||
<li><a href="/boolean-logic.html">Boolean Logic</a></li>
|
||||
<li><a href="/conditionals.html">Conditionals</a></li>
|
||||
<li><a href="/loops.html">Loops</a></li>
|
||||
<li><a href="/arrays.html">Arrays</a></li>
|
||||
<li><a href="/functions.html">Functions</a></li>
|
||||
<li><a href="/classes.html">Classes</a></li>
|
||||
</ol>
|
||||
<a href="/credits.html">Credits</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
51
docs/credits.html
Normal file
@@ -0,0 +1,51 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<title>PHP Apprentice - Credits</title>
|
||||
<meta name="description" content="A site for learning how to use PHP">
|
||||
|
||||
<link rel="stylesheet" href="/css/site.css">
|
||||
<link rel="icon" href="/favicon-32.png">
|
||||
<script src="/js/site.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div class="container center">
|
||||
<div class="grid-toc">
|
||||
<div>
|
||||
<h1>Credits</h1>
|
||||
<p>
|
||||
PHP Apprentice was inspired by
|
||||
<a href="https://gobyexample.com/">Go By Example</a> and by <a href="https://elixirschool.com/">Elixir School</a>. Both sites offer excellent, quality documentation in Go and Elixir and I want PHP Apprentice to provide the same
|
||||
experience for the PHP programming language.
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<div class="table-of-contents">
|
||||
<h4>Table of Contents</h4>
|
||||
<a href="/index.html">Preface</a>
|
||||
<ol>
|
||||
<li><a href="/basics.html">Basics</a></li>
|
||||
<li><a href="/variables.html">Variables</a></li>
|
||||
<li><a href="/arithmetic.html">Arithmetic</a></li>
|
||||
<li><a href="/comparisons.html">Comparisons</a></li>
|
||||
<li><a href="/boolean-logic.html">Boolean Logic</a></li>
|
||||
<li><a href="/conditionals.html">Conditionals</a></li>
|
||||
<li><a href="/loops.html">Loops</a></li>
|
||||
<li><a href="/arrays.html">Arrays</a></li>
|
||||
<li><a href="/functions.html">Functions</a></li>
|
||||
<li><a href="/classes.html">Classes</a></li>
|
||||
</ol>
|
||||
<a href="/credits.html">Credits</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
418
docs/css/site.css
Normal file
@@ -0,0 +1,418 @@
|
||||
/*
|
||||
Solarized Color Schemes originally by Ethan Schoonover
|
||||
http://ethanschoonover.com/solarized
|
||||
|
||||
Ported for PrismJS by Hector Matos
|
||||
Website: https://krakendev.io
|
||||
Twitter Handle: https://twitter.com/allonsykraken)
|
||||
*/
|
||||
|
||||
/*
|
||||
SOLARIZED HEX
|
||||
--------- -------
|
||||
base03 #002b36
|
||||
base02 #073642
|
||||
base01 #586e75
|
||||
base00 #657b83
|
||||
base0 #839496
|
||||
base1 #93a1a1
|
||||
base2 #eee8d5
|
||||
base3 #fdf6e3
|
||||
yellow #b58900
|
||||
orange #cb4b16
|
||||
red #dc322f
|
||||
magenta #d33682
|
||||
violet #6c71c4
|
||||
blue #268bd2
|
||||
cyan #2aa198
|
||||
green #859900
|
||||
*/
|
||||
|
||||
code[class*="language-"],
|
||||
pre[class*="language-"] {
|
||||
color: #657b83; /* base00 */
|
||||
font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
|
||||
text-align: left;
|
||||
white-space: pre;
|
||||
word-spacing: normal;
|
||||
word-break: normal;
|
||||
word-wrap: normal;
|
||||
|
||||
line-height: 1.5;
|
||||
|
||||
-moz-tab-size: 4;
|
||||
-o-tab-size: 4;
|
||||
tab-size: 4;
|
||||
|
||||
-webkit-hyphens: none;
|
||||
-ms-hyphens: none;
|
||||
hyphens: none;
|
||||
}
|
||||
|
||||
pre[class*="language-"]::-moz-selection, pre[class*="language-"] ::-moz-selection,
|
||||
code[class*="language-"]::-moz-selection, code[class*="language-"] ::-moz-selection {
|
||||
background: #073642; /* base02 */
|
||||
}
|
||||
|
||||
pre[class*="language-"]::selection, pre[class*="language-"] ::selection,
|
||||
code[class*="language-"]::selection, code[class*="language-"] ::selection {
|
||||
background: #073642; /* base02 */
|
||||
}
|
||||
|
||||
/* Code blocks */
|
||||
|
||||
pre[class*="language-"] {
|
||||
padding: 1em;
|
||||
margin: .5em 0;
|
||||
overflow: auto;
|
||||
border-radius: 0.3em;
|
||||
}
|
||||
|
||||
:not(pre) > code[class*="language-"],
|
||||
pre[class*="language-"] {
|
||||
background-color: #fdf6e3; /* base3 */
|
||||
}
|
||||
|
||||
/* Inline code */
|
||||
|
||||
:not(pre) > code[class*="language-"] {
|
||||
padding: .1em;
|
||||
border-radius: .3em;
|
||||
}
|
||||
|
||||
.token.comment,
|
||||
.token.prolog,
|
||||
.token.doctype,
|
||||
.token.cdata {
|
||||
color: #93a1a1; /* base1 */
|
||||
}
|
||||
|
||||
.token.punctuation {
|
||||
color: #586e75; /* base01 */
|
||||
}
|
||||
|
||||
.namespace {
|
||||
opacity: .7;
|
||||
}
|
||||
|
||||
.token.property,
|
||||
.token.tag,
|
||||
.token.boolean,
|
||||
.token.number,
|
||||
.token.constant,
|
||||
.token.symbol,
|
||||
.token.deleted {
|
||||
color: #268bd2; /* blue */
|
||||
}
|
||||
|
||||
.token.selector,
|
||||
.token.attr-name,
|
||||
.token.string,
|
||||
.token.char,
|
||||
.token.builtin,
|
||||
.token.url,
|
||||
.token.inserted {
|
||||
color: #2aa198; /* cyan */
|
||||
}
|
||||
|
||||
.token.entity {
|
||||
color: #657b83; /* base00 */
|
||||
background: #eee8d5; /* base2 */
|
||||
}
|
||||
|
||||
.token.atrule,
|
||||
.token.attr-value,
|
||||
.token.keyword {
|
||||
color: #859900; /* green */
|
||||
}
|
||||
|
||||
.token.function,
|
||||
.token.class-name {
|
||||
color: #b58900; /* yellow */
|
||||
}
|
||||
|
||||
.token.regex,
|
||||
.token.important,
|
||||
.token.variable {
|
||||
color: #cb4b16; /* orange */
|
||||
}
|
||||
|
||||
.token.important,
|
||||
.token.bold {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.token.italic {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.token.entity {
|
||||
cursor: help;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: Palatino, "Palatino Linotype", "Palatino LT STD", "Book Antiqua", Georgia, serif;
|
||||
font-size: 16px;
|
||||
padding-top: 1em;
|
||||
padding-bottom: 1em;
|
||||
}
|
||||
|
||||
pre, code {
|
||||
font-family: Consolas, monaco, monospace;
|
||||
font-size: 16px;
|
||||
margin: 0 !important;
|
||||
border-radius: 0 !important;
|
||||
padding-top: 0.5em !important;
|
||||
padding-bottom: 0.5em !important;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #2AA198; /* #4078f2 */
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
text-decoration: underline;
|
||||
color: #1D6E68;
|
||||
}
|
||||
|
||||
p {
|
||||
max-width: 40em;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4 {
|
||||
margin: 1.414em 0 0.5em;
|
||||
font-weight: inherit;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin-top: 0;
|
||||
font-size: 2.441em;
|
||||
}
|
||||
|
||||
h2 {font-size: 1.953em;}
|
||||
|
||||
h3 {font-size: 1.563em;}
|
||||
|
||||
h4 {font-size: 1.25em;}
|
||||
|
||||
small, .font_small {font-size: 0.8em;}
|
||||
|
||||
button {
|
||||
font-size: 1em;
|
||||
background-color: transparent;
|
||||
border: 0;
|
||||
cursor: pointer;
|
||||
padding: 0;
|
||||
color: #2AA198;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
color: #1D6E68;
|
||||
}
|
||||
|
||||
button .icon {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
button .icon svg {
|
||||
fill: #2AA198;
|
||||
}
|
||||
|
||||
button:hover .icon svg {
|
||||
fill: #1D6E68;
|
||||
}
|
||||
|
||||
.button {
|
||||
background-color: #2AA198;
|
||||
color: #FFF;
|
||||
padding: 0.5em 1em;
|
||||
border-radius: 1em;
|
||||
}
|
||||
|
||||
.button:hover {
|
||||
color: #FFF;
|
||||
background-color: #1D6E68;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.button .icon {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.button .icon svg {
|
||||
fill: #FFF;
|
||||
}
|
||||
|
||||
.clearfix:after {
|
||||
content: "";
|
||||
display: table;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.container {
|
||||
width: 90%;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
@media only screen and (min-width: 33.75em) { /* 540px */
|
||||
.container {
|
||||
width: 80%;
|
||||
}
|
||||
}
|
||||
|
||||
.center {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.right {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.doc {
|
||||
padding: 0.5em 0;
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.description {
|
||||
max-width: 25em;
|
||||
}
|
||||
|
||||
.grid-code {
|
||||
display: grid;
|
||||
grid-template-columns: 400px 1fr;
|
||||
grid-column-gap: 3em;
|
||||
}
|
||||
|
||||
.grid-code .code {
|
||||
background-color: #FDF6E3;
|
||||
}
|
||||
|
||||
.grid-toc {
|
||||
display: grid;
|
||||
grid-template-columns: 2fr 1fr;
|
||||
grid-column-gap: 3em;
|
||||
}
|
||||
|
||||
.navigate-links {
|
||||
margin: 1em 0;
|
||||
float: right;
|
||||
}
|
||||
|
||||
.navigate-links .icon {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.navigate-links .icon svg {
|
||||
fill: #2AA198;
|
||||
}
|
||||
|
||||
.navigate-links:hover .icon svg {
|
||||
fill: #1D6E68;
|
||||
}
|
||||
|
||||
.navigate-links a {
|
||||
margin-left: 1em;
|
||||
}
|
||||
|
||||
.navigate-links a:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.table-of-contents {
|
||||
padding: 2em;
|
||||
}
|
||||
|
||||
.table-of-contents ol {
|
||||
margin: 1em 0;
|
||||
padding-left: 1em;
|
||||
}
|
||||
|
||||
.table-of-contents .section-title {
|
||||
font-weight: bold;
|
||||
font-size: 0.8em;
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
.icon {
|
||||
width: 1em;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.home-title-wrapper {
|
||||
display: grid;
|
||||
grid-template-columns: 175px 1fr;
|
||||
grid-template-rows: 1fr 1fr;
|
||||
}
|
||||
|
||||
.home-title {
|
||||
|
||||
}
|
||||
|
||||
.home-subtitle {
|
||||
margin-top: 0;
|
||||
grid-column-start: 2;
|
||||
grid-column-end: 3;
|
||||
}
|
||||
|
||||
.home-logo {
|
||||
grid-row-start: 1;
|
||||
grid-row-end: 3;
|
||||
}
|
||||
|
||||
.home-logo svg {
|
||||
width: 150px;
|
||||
height: 100px;
|
||||
}
|
||||
|
||||
.menu {
|
||||
margin-left: 2em;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
.modal {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 50;
|
||||
overflow: auto;
|
||||
background-color: rgba(0, 0, 0, .4);
|
||||
}
|
||||
|
||||
.modal-content {
|
||||
display: block;
|
||||
position: relative;
|
||||
padding: 1em;
|
||||
background-color: #FFF;
|
||||
max-width: 15em;
|
||||
height: 100%;
|
||||
-webkit-animation-name: animateleft;
|
||||
animation-name: animateleft;
|
||||
-webkit-animation-duration: .4s;
|
||||
animation-duration: .4s;
|
||||
overflow: scroll;
|
||||
box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
|
||||
.closed {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@-webkit-keyframes animateleft {
|
||||
from {left: -300px; opacity: 0}
|
||||
to {left: 0; opacity: 1}
|
||||
}
|
||||
|
||||
@keyframes animateleft {
|
||||
from {left: -300px; opacity: 0}
|
||||
to {left: 0; opacity: 1}
|
||||
}
|
BIN
docs/favicon-32.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
95
docs/functions.html
Normal file
@@ -0,0 +1,95 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<title>Functions</title>
|
||||
<meta name="description" content="">
|
||||
|
||||
<link rel="stylesheet" href="/css/site.css">
|
||||
<link rel="icon" href="/favicon-32.png">
|
||||
<script src="/js/site.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div class="menu">
|
||||
<button class="menu-button" title="Open Menu">
|
||||
<div class="icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M0 3h20v2H0V3zm0 6h20v2H0V9zm0 6h20v2H0v-2z"/></svg></div>
|
||||
Menu
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="container center">
|
||||
<h1>Functions</h1>
|
||||
<h3 class="subtitle">Reusable code</h3>
|
||||
<div class="grid-code"><div class="doc"></div><div class="code"><pre><code class="language-php"><?php
|
||||
|
||||
</code></pre></div><div class="doc">A function allows you to store code under a name and then execute that code later.</div><div class="code"><pre><code class="language-php">
|
||||
</code></pre></div><div class="doc">A function always starts with the function keyword followed by the name with parentheses and then opening and closing curly braces around the code.</div><div class="code"><pre><code class="language-php">function hello_world() {
|
||||
echo "hello world\n";
|
||||
}
|
||||
|
||||
</code></pre></div><div class="doc">To call the function, use the function name with parentheses.</div><div class="code"><pre><code class="language-php">hello_world();
|
||||
|
||||
</code></pre></div><div class="doc">You can set up values to be passed into a function. To do so, write variables in between the function parentheses. Each one should be separated by a comma.</div><div class="code"><pre><code class="language-php">function greet($firstname, $lastname) {
|
||||
echo "hello $firstname $lastname\n";
|
||||
}
|
||||
|
||||
</code></pre></div><div class="doc">Then, you can pass in values when calling a function. In the greet function, 'John' is assigned to $firstname and 'Smith' is assigned to $lastname.</div><div class="code"><pre><code class="language-php">greet('John', 'Smith');
|
||||
|
||||
</code></pre></div><div class="doc">You can also return a value from a function. You can only return a single value from a function.</div><div class="code"><pre><code class="language-php">function capitalize($value) {
|
||||
return strtoupper($value);
|
||||
}
|
||||
|
||||
</code></pre></div><div class="doc">When calling a function, it will output the return value which you can load into a variable.</div><div class="code"><pre><code class="language-php">$animal = capitalize('dog');
|
||||
echo "$animal\n";
|
||||
|
||||
</code></pre></div><div class="doc">You can also create nameless functions called closures. Closures can be stored in variables or passed into other functions.</div><div class="code"><pre><code class="language-php">$sum = function ($a, $b) {
|
||||
return $a + $b;
|
||||
};
|
||||
|
||||
</code></pre></div><div class="doc">You can execute a closure by putting parentheses after the variable.</div><div class="code"><pre><code class="language-php">echo $sum(1, 2) . "\n";
|
||||
</code></pre></div></div>
|
||||
<div class="clearfix"></div>
|
||||
<div class="navigate-links">
|
||||
<a href="/arrays.html" title="Previous">
|
||||
<div class="icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M10 20a10 10 0 1 1 0-20 10 10 0 0 1 0 20zm8-10a8 8 0 1 0-16 0 8 8 0 0 0 16 0zM7.46 9.3L11 5.75l1.41 1.41L9.6 10l2.82 2.83L11 14.24 6.76 10l.7-.7z"/></svg></div>
|
||||
Previous
|
||||
</a>
|
||||
<a href="/classes.html" title="Next">
|
||||
Next
|
||||
<div class="icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M10 0a10 10 0 1 1 0 20 10 10 0 0 1 0-20zM2 10a8 8 0 1 0 16 0 8 8 0 0 0-16 0zm10.54.7L9 14.25l-1.41-1.41L10.4 10 7.6 7.17 9 5.76 13.24 10l-.7.7z"/></svg></div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal closed">
|
||||
<div class="modal-content">
|
||||
<button class="modal-button right" title="Close">
|
||||
<div class="icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M2.93 17.07A10 10 0 1 1 17.07 2.93 10 10 0 0 1 2.93 17.07zm1.41-1.41A8 8 0 1 0 15.66 4.34 8 8 0 0 0 4.34 15.66zm9.9-8.49L11.41 10l2.83 2.83-1.41 1.41L10 11.41l-2.83 2.83-1.41-1.41L8.59 10 5.76 7.17l1.41-1.41L10 8.59l2.83-2.83 1.41 1.41z"/></svg></div>
|
||||
</button>
|
||||
<div class="table-of-contents">
|
||||
<h4>Table of Contents</h4>
|
||||
<a href="/index.html">Preface</a>
|
||||
<ol>
|
||||
<li><a href="/basics.html">Basics</a></li>
|
||||
<li><a href="/variables.html">Variables</a></li>
|
||||
<li><a href="/arithmetic.html">Arithmetic</a></li>
|
||||
<li><a href="/comparisons.html">Comparisons</a></li>
|
||||
<li><a href="/boolean-logic.html">Boolean Logic</a></li>
|
||||
<li><a href="/conditionals.html">Conditionals</a></li>
|
||||
<li><a href="/loops.html">Loops</a></li>
|
||||
<li><a href="/arrays.html">Arrays</a></li>
|
||||
<li><a href="/functions.html">Functions</a></li>
|
||||
<li><a href="/classes.html">Classes</a></li>
|
||||
</ol>
|
||||
<a href="/credits.html">Credits</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
109
docs/index.html
Normal file
@@ -0,0 +1,109 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<title>PHP Apprentice</title>
|
||||
<meta name="description" content="A site for learning how to use PHP">
|
||||
|
||||
<link rel="stylesheet" href="/css/site.css">
|
||||
<link rel="icon" href="/favicon-32.png">
|
||||
<script src="/js/site.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div class="container center">
|
||||
<div class="grid-toc">
|
||||
<div>
|
||||
<div class="home-title-wrapper">
|
||||
<div class="home-logo"><?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="404px" height="249px" viewBox="0 0 404 249" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 49.3 (51167) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>elephant</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<defs>
|
||||
<path d="M114.406262,33.0409234 C116.906654,33.0409234 198.587086,33.0409234 212.851562,33.0409234 C236.23173,33.0409234 290.966457,24.8360253 302.9375,21.828125 C322.709617,16.8600902 345.780295,41.1710486 350.739426,66.2834373 C355.388936,89.8279414 351.557615,107.060167 350.739426,117.478001 C348.492267,146.090655 340.913827,171.751032 340.913827,188.521289 C340.913827,211.397578 342.398654,228.60813 345.368307,240.152946 C338.345502,243.384315 332.63113,245 328.225191,245 C323.819252,245 319.466187,243.384315 315.165998,240.152946 C315.165998,212.852821 315.165998,195.642269 315.165998,188.521289 C315.165998,182.659437 313.041474,171.488839 308.792425,155.009494 C278.81585,157.935469 251.486979,159.893283 226.805814,160.882937 C202.124648,161.87259 177.935757,159.914776 154.23914,155.009494 C151.904793,170.439973 150.468074,183.375856 149.928982,193.817144 C149.389891,204.258431 148.391339,219.703699 146.933325,240.152946 C138.57305,243.384315 132.573934,245 128.935979,245 C125.298024,245 120.454785,243.384315 114.406262,240.152946 C121.029663,211.242836 124.190445,189.722491 123.888609,175.59191 C122.851956,127.060632 111.761968,33.0409234 114.406262,33.0409234 Z" id="path-1"></path>
|
||||
<filter x="-2.7%" y="-2.0%" width="103.8%" height="104.0%" filterUnits="objectBoundingBox" id="filter-2">
|
||||
<feMorphology radius="0.5" operator="dilate" in="SourceAlpha" result="shadowSpreadOuter1"></feMorphology>
|
||||
<feOffset dx="-2" dy="0" in="shadowSpreadOuter1" result="shadowOffsetOuter1"></feOffset>
|
||||
<feGaussianBlur stdDeviation="1" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
|
||||
<feComposite in="shadowBlurOuter1" in2="SourceAlpha" operator="out" result="shadowBlurOuter1"></feComposite>
|
||||
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
|
||||
</filter>
|
||||
<path d="M123.708835,0.204671096 C110.38422,-0.782948431 96.8541352,1.80367512 83.1185794,7.96454174 C70.5914337,12.5905258 61.8564763,19.2306573 56.9137071,27.8849362 C45.3780726,48.0826419 45.2190029,54.1139776 45.2190029,74.89832 C45.2190029,80.5496319 45.2190029,94.2775295 45.2190029,116.082013 C44.8941776,135.814054 42.9028153,149.847335 39.2449159,158.181856 C35.7666671,166.107044 22.7617193,171.939345 0.23007254,175.678759 C0.0766908466,178.530744 -4.04672828e-16,180.785883 0,182.444176 C-4.04672828e-16,184.102469 0.742211413,186.619924 2.22663424,189.996543 C19.3683356,190.134613 33.6991251,186.137222 45.2190029,178.004371 C58.0689401,168.932519 56.2252902,163.797983 62.486142,147.454285 C66.2191971,137.709297 68.3704403,127.251873 68.9398717,116.082013 C98.4645478,120.955097 116.720869,123.391639 123.708835,123.391639 C134.190784,123.391639 148.793717,120.923091 160.10709,103.338129 C171.533853,85.5769196 172.420694,75.0592376 174.453335,67.1621734 C177.277215,56.1910529 186,34.1766174 186,21.1547558 C186,8.13289413 144.421355,1.73988173 123.708835,0.204671096 Z" id="path-3"></path>
|
||||
<filter x="-1.9%" y="-1.3%" width="104.8%" height="104.7%" filterUnits="objectBoundingBox" id="filter-4">
|
||||
<feMorphology radius="0.5" operator="dilate" in="SourceAlpha" result="shadowSpreadOuter1"></feMorphology>
|
||||
<feOffset dx="1" dy="2" in="shadowSpreadOuter1" result="shadowOffsetOuter1"></feOffset>
|
||||
<feGaussianBlur stdDeviation="1" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
|
||||
<feComposite in="shadowBlurOuter1" in2="SourceAlpha" operator="out" result="shadowBlurOuter1"></feComposite>
|
||||
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
|
||||
</filter>
|
||||
</defs>
|
||||
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="Elephant" transform="translate(-120.000000, -62.000000)">
|
||||
<g id="elephant" transform="translate(122.000000, 63.000000)">
|
||||
<path d="M292,154 L292,229.687017 C297.80012,232.562339 302.466787,234 306,234 C309.533213,234 314.19988,232.562339 320,229.687017 L320,154 L292,154 Z" id="Path-3" stroke="#979797" fill="#D8D8D8"></path>
|
||||
<path d="M113.089613,112 C112.215697,146.301082 110.868891,171.05041 109.049195,186.247987 C107.229499,201.445563 103.879767,215.920359 99,229.672376 C104.837247,232.557459 109.533784,234 113.089613,234 C116.645442,234 121.34198,232.557459 127.179226,229.672376 L134,112 L113.089613,112 Z" id="Path-3-Copy" stroke="#979797" fill="#D8D8D8"></path>
|
||||
<g id="Path">
|
||||
<use fill="black" fill-opacity="1" filter="url(#filter-2)" xlink:href="#path-1"></use>
|
||||
<use stroke="#979797" stroke-width="1" fill="#D8D8D8" fill-rule="evenodd" xlink:href="#path-1"></use>
|
||||
</g>
|
||||
<g id="Path-2">
|
||||
<use fill="black" fill-opacity="1" filter="url(#filter-4)" xlink:href="#path-3"></use>
|
||||
<use stroke="#979797" stroke-width="1" fill="#D8D8D8" fill-rule="evenodd" xlink:href="#path-3"></use>
|
||||
</g>
|
||||
<circle id="Oval" fill="#000000" cx="77" cy="76" r="5"></circle>
|
||||
<path d="M394.04451,154.695284 C387.335643,135.817928 382.463422,123.3603 379.427845,117.322398 C376.392268,111.284497 366.955141,94.8960125 351.116464,68.1569449 L353,83.4050009 C362.468082,99.4723027 368.913046,110.778102 372.334893,117.322398 C380.679064,133.280662 386.198146,152.11787 388.617876,158.078886 C390.422602,162.524839 392.314008,171.103712 394.04451,185.164806 C394.940381,192.444154 397.167522,203.5 399.948259,203.5 C402.726203,203.5 400.982103,193.180619 399.948259,185.164806 C399.25903,179.820931 397.291114,169.664424 394.04451,154.695284 Z" id="Path-4" stroke="#979797" fill="#D8D8D8"></path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg></div>
|
||||
<h1 class="home-title">PHP Apprentice <em>(beta)</em></h1>
|
||||
<h3 class="home-subtitle">A site for learning how to use PHP</h3>
|
||||
</div>
|
||||
<p>
|
||||
The goal of PHP Apprentice is to be an easy to understand resource for learning how to write good code in the PHP programming language. There are a lot of PHP tutorials on the internet that use outdated libraries, insecure programming practices or inefficient code. I want this site to show how to write PHP code with quality.
|
||||
</p>
|
||||
<p>
|
||||
The site currently has content for learning the basics of PHP. In the future, more pages will be added for more advanced topics like building websites, database integration and security.
|
||||
</p>
|
||||
<p>
|
||||
PHP Apprentice is currently a work in progress (hence "beta" is included in the title). If you would like to contribute or request a certain discussion topic, checkout the <a href="https://github.com/restoreddev/php-apprentice" target="_blank">GitHub repository</a>.
|
||||
</p>
|
||||
<p>
|
||||
To get started, you will need to install PHP 7.1, have a text editor and open your terminal.
|
||||
Each example in PHP Apprentice can by typed into a PHP file and executed in the terminal.
|
||||
Let's get started! 😃
|
||||
</p>
|
||||
<a href="/basics.html" class="button">
|
||||
<div class="icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M6 4H5a1 1 0 1 1 0-2h11V1a1 1 0 0 0-1-1H4a2 2 0 0 0-2 2v16c0 1.1.9 2 2 2h12a2 2 0 0 0 2-2V5a1 1 0 0 0-1-1h-7v8l-2-2-2 2V4z"/></svg></div>
|
||||
Open First Chapter
|
||||
</a>
|
||||
</div>
|
||||
<div>
|
||||
<div class="table-of-contents">
|
||||
<h4>Table of Contents</h4>
|
||||
<a href="/index.html">Preface</a>
|
||||
<ol>
|
||||
<li><a href="/basics.html">Basics</a></li>
|
||||
<li><a href="/variables.html">Variables</a></li>
|
||||
<li><a href="/arithmetic.html">Arithmetic</a></li>
|
||||
<li><a href="/comparisons.html">Comparisons</a></li>
|
||||
<li><a href="/boolean-logic.html">Boolean Logic</a></li>
|
||||
<li><a href="/conditionals.html">Conditionals</a></li>
|
||||
<li><a href="/loops.html">Loops</a></li>
|
||||
<li><a href="/arrays.html">Arrays</a></li>
|
||||
<li><a href="/functions.html">Functions</a></li>
|
||||
<li><a href="/classes.html">Classes</a></li>
|
||||
</ol>
|
||||
<a href="/credits.html">Credits</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
1103
docs/js/site.js
Normal file
106
docs/loops.html
Normal file
@@ -0,0 +1,106 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<title>Loops</title>
|
||||
<meta name="description" content="">
|
||||
|
||||
<link rel="stylesheet" href="/css/site.css">
|
||||
<link rel="icon" href="/favicon-32.png">
|
||||
<script src="/js/site.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div class="menu">
|
||||
<button class="menu-button" title="Open Menu">
|
||||
<div class="icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M0 3h20v2H0V3zm0 6h20v2H0V9zm0 6h20v2H0v-2z"/></svg></div>
|
||||
Menu
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="container center">
|
||||
<h1>Loops</h1>
|
||||
<h3 class="subtitle">Increase your repetitions</h3>
|
||||
<div class="grid-code"><div class="doc"></div><div class="code"><pre><code class="language-php"><?php
|
||||
|
||||
</code></pre></div><div class="doc">A loop tells PHP to run a block of code more than once. A classic loop is a while loop. A "while" loop will continue to run the block of code as long as the value in parentheses is true.</div><div class="code"><pre><code class="language-php">$num = 5;
|
||||
while ($num > 0) {
|
||||
echo "While loop $num\n";
|
||||
--$num;
|
||||
}
|
||||
|
||||
</code></pre></div><div class="doc">A "do while" loop is similar to a "while" loop except it always runs at least one iteration. In a classic "while" loop, no iterations may be executed if the value in parentheses is false. In a "do while", the boolean check is not done until after the execution of an iteration.</div><div class="code"><pre><code class="language-php">$num = 0;
|
||||
do {
|
||||
echo "Do while $num\n";
|
||||
++$num;
|
||||
} while ($num < 5);
|
||||
|
||||
</code></pre></div><div class="doc">"for" loops allow you to create a more concise while loop. Inside the parentheses, the left section creates a variable before the loop starts, the middle section is the check that is done at the beginning of each loop and the third section is executed after each loop.</div><div class="code"><pre><code class="language-php">for ($i = 0; $i < 10; $i++) {
|
||||
echo "For loop $i\n";
|
||||
}
|
||||
|
||||
</code></pre></div><div class="doc">A "foreach" loop allows you to easily loop over an array. An array is a list of data stored together. The "as" keyword lets you assign a variable to the value in the array for the current iteration of the loop.</div><div class="code"><pre><code class="language-php">$set = [1, 2, 3, 4, 5];
|
||||
foreach ($set as $num) {
|
||||
echo "Array value $num\n";
|
||||
}
|
||||
|
||||
</code></pre></div><div class="doc">In loops, you can use the keyword "break" to stop the loop execution no matter how many more iterations should run.</div><div class="code"><pre><code class="language-php">$values = ['one', 'two', 'three'];
|
||||
foreach ($values as $value) {
|
||||
if ($value === 'two') {
|
||||
break;
|
||||
}
|
||||
echo "Break $value\n";
|
||||
}
|
||||
|
||||
</code></pre></div><div class="doc">The "continue" keyword stops executing the current loop iteration, but then allows the loop to continue with other iterations.</div><div class="code"><pre><code class="language-php">$values = ['one', 'skip', 'three'];
|
||||
foreach ($values as $value) {
|
||||
if ($value === 'skip') {
|
||||
continue;
|
||||
}
|
||||
echo "Continue $value\n";
|
||||
}
|
||||
</code></pre></div></div>
|
||||
<div class="clearfix"></div>
|
||||
<div class="navigate-links">
|
||||
<a href="/conditionals.html" title="Previous">
|
||||
<div class="icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M10 20a10 10 0 1 1 0-20 10 10 0 0 1 0 20zm8-10a8 8 0 1 0-16 0 8 8 0 0 0 16 0zM7.46 9.3L11 5.75l1.41 1.41L9.6 10l2.82 2.83L11 14.24 6.76 10l.7-.7z"/></svg></div>
|
||||
Previous
|
||||
</a>
|
||||
<a href="/arrays.html" title="Next">
|
||||
Next
|
||||
<div class="icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M10 0a10 10 0 1 1 0 20 10 10 0 0 1 0-20zM2 10a8 8 0 1 0 16 0 8 8 0 0 0-16 0zm10.54.7L9 14.25l-1.41-1.41L10.4 10 7.6 7.17 9 5.76 13.24 10l-.7.7z"/></svg></div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal closed">
|
||||
<div class="modal-content">
|
||||
<button class="modal-button right" title="Close">
|
||||
<div class="icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M2.93 17.07A10 10 0 1 1 17.07 2.93 10 10 0 0 1 2.93 17.07zm1.41-1.41A8 8 0 1 0 15.66 4.34 8 8 0 0 0 4.34 15.66zm9.9-8.49L11.41 10l2.83 2.83-1.41 1.41L10 11.41l-2.83 2.83-1.41-1.41L8.59 10 5.76 7.17l1.41-1.41L10 8.59l2.83-2.83 1.41 1.41z"/></svg></div>
|
||||
</button>
|
||||
<div class="table-of-contents">
|
||||
<h4>Table of Contents</h4>
|
||||
<a href="/index.html">Preface</a>
|
||||
<ol>
|
||||
<li><a href="/basics.html">Basics</a></li>
|
||||
<li><a href="/variables.html">Variables</a></li>
|
||||
<li><a href="/arithmetic.html">Arithmetic</a></li>
|
||||
<li><a href="/comparisons.html">Comparisons</a></li>
|
||||
<li><a href="/boolean-logic.html">Boolean Logic</a></li>
|
||||
<li><a href="/conditionals.html">Conditionals</a></li>
|
||||
<li><a href="/loops.html">Loops</a></li>
|
||||
<li><a href="/arrays.html">Arrays</a></li>
|
||||
<li><a href="/functions.html">Functions</a></li>
|
||||
<li><a href="/classes.html">Classes</a></li>
|
||||
</ol>
|
||||
<a href="/credits.html">Credits</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
4
docs/manifest.json
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"js/site.js": "/js/site.js",
|
||||
"css/site.css": "/css/site.css"
|
||||
}
|
87
docs/variables.html
Normal file
@@ -0,0 +1,87 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<title>Variables</title>
|
||||
<meta name="description" content="">
|
||||
|
||||
<link rel="stylesheet" href="/css/site.css">
|
||||
<link rel="icon" href="/favicon-32.png">
|
||||
<script src="/js/site.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div class="menu">
|
||||
<button class="menu-button" title="Open Menu">
|
||||
<div class="icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M0 3h20v2H0V3zm0 6h20v2H0V9zm0 6h20v2H0v-2z"/></svg></div>
|
||||
Menu
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="container center">
|
||||
<h1>Variables</h1>
|
||||
<h3 class="subtitle">The building blocks of PHP</h3>
|
||||
<div class="grid-code"><div class="doc"></div><div class="code"><pre><code class="language-php"><?php
|
||||
|
||||
</code></pre></div><div class="doc">The variable is the basic building block of any programming language. In PHP, all variables start with a dollar sign.</div><div class="code"><pre><code class="language-php">$greeting;
|
||||
|
||||
</code></pre></div><div class="doc">To set data in a variable, you put an equals sign after it and some data.</div><div class="code"><pre><code class="language-php">$greeting = 'Hello World!';
|
||||
|
||||
</code></pre></div><div class="doc">Once you create a variable, you can use it again in other commands and functions.</div><div class="code"><pre><code class="language-php">echo $greeting;
|
||||
|
||||
</code></pre></div><div class="doc">After the dollar sign, a PHP variable must have an alphabetic character or underscore. Also, variables are case sensitive.</div><div class="code"><pre><code class="language-php">$_var = 'I am a variable with an underscore!';
|
||||
$Var = 'I am a variable with a capital letter!';
|
||||
$var = 'I am a new variable';
|
||||
|
||||
</code></pre></div><div class="doc">Variables can hold many different types of data, but there are four simple ones you can try now. An int is a number without a decimal place. A float is a number with a decimal place. A boolean can be two values: true or false. Last, there is a string, a collection of characters.</div><div class="code"><pre><code class="language-php">$int = 1;
|
||||
$float = 100.10;
|
||||
$bool = true;
|
||||
$string = 'I am a string';
|
||||
|
||||
</code></pre></div><div class="doc">In other programming languages, you have to write what type of data the variable will contain. PHP keeps it simple by allowing you to put any type of data in a variable, including already used variables.</div><div class="code"><pre><code class="language-php">$number = 1;
|
||||
$number = 'one';
|
||||
</code></pre></div></div>
|
||||
<div class="clearfix"></div>
|
||||
<div class="navigate-links">
|
||||
<a href="/basics.html" title="Previous">
|
||||
<div class="icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M10 20a10 10 0 1 1 0-20 10 10 0 0 1 0 20zm8-10a8 8 0 1 0-16 0 8 8 0 0 0 16 0zM7.46 9.3L11 5.75l1.41 1.41L9.6 10l2.82 2.83L11 14.24 6.76 10l.7-.7z"/></svg></div>
|
||||
Previous
|
||||
</a>
|
||||
<a href="/arithmetic.html" title="Next">
|
||||
Next
|
||||
<div class="icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M10 0a10 10 0 1 1 0 20 10 10 0 0 1 0-20zM2 10a8 8 0 1 0 16 0 8 8 0 0 0-16 0zm10.54.7L9 14.25l-1.41-1.41L10.4 10 7.6 7.17 9 5.76 13.24 10l-.7.7z"/></svg></div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal closed">
|
||||
<div class="modal-content">
|
||||
<button class="modal-button right" title="Close">
|
||||
<div class="icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M2.93 17.07A10 10 0 1 1 17.07 2.93 10 10 0 0 1 2.93 17.07zm1.41-1.41A8 8 0 1 0 15.66 4.34 8 8 0 0 0 4.34 15.66zm9.9-8.49L11.41 10l2.83 2.83-1.41 1.41L10 11.41l-2.83 2.83-1.41-1.41L8.59 10 5.76 7.17l1.41-1.41L10 8.59l2.83-2.83 1.41 1.41z"/></svg></div>
|
||||
</button>
|
||||
<div class="table-of-contents">
|
||||
<h4>Table of Contents</h4>
|
||||
<a href="/index.html">Preface</a>
|
||||
<ol>
|
||||
<li><a href="/basics.html">Basics</a></li>
|
||||
<li><a href="/variables.html">Variables</a></li>
|
||||
<li><a href="/arithmetic.html">Arithmetic</a></li>
|
||||
<li><a href="/comparisons.html">Comparisons</a></li>
|
||||
<li><a href="/boolean-logic.html">Boolean Logic</a></li>
|
||||
<li><a href="/conditionals.html">Conditionals</a></li>
|
||||
<li><a href="/loops.html">Loops</a></li>
|
||||
<li><a href="/arrays.html">Arrays</a></li>
|
||||
<li><a href="/functions.html">Functions</a></li>
|
||||
<li><a href="/classes.html">Classes</a></li>
|
||||
</ol>
|
||||
<a href="/credits.html">Credits</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
8820
package-lock.json
generated
Normal file
35
package.json
Normal file
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"name": "php-apprentice",
|
||||
"version": "1.0.0",
|
||||
"description": "A website for learning PHP",
|
||||
"directories": {
|
||||
"doc": "docs"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"build": "./node_modules/.bin/encore dev",
|
||||
"watch": "./node_modules/.bin/encore dev --watch",
|
||||
"prod": "./node_modules/.bin/encore production"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/restoreddev/php-apprentice.git"
|
||||
},
|
||||
"author": "",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/restoreddev/php-apprentice/issues"
|
||||
},
|
||||
"homepage": "https://github.com/restoreddev/php-apprentice#readme",
|
||||
"devDependencies": {
|
||||
"@symfony/webpack-encore": "^0.20.1",
|
||||
"autoprefixer": "^8.6.5",
|
||||
"postcss-import": "^11.1.0",
|
||||
"postcss-loader": "^2.1.5",
|
||||
"postcss-simple-vars": "^4.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"babel-plugin-prismjs": "^1.0.2",
|
||||
"prismjs": "^1.15.0"
|
||||
}
|
||||
}
|
15
phpunit.xml
Normal file
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<phpunit
|
||||
bootstrap="vendor/autoload.php"
|
||||
colors="true"
|
||||
convertErrorsToExceptions="true"
|
||||
convertNoticesToExceptions="true"
|
||||
convertWarningsToExceptions="true"
|
||||
processIsolation="false"
|
||||
stopOnFailure="false">
|
||||
<testsuites>
|
||||
<testsuite name="Unit">
|
||||
<directory suffix="Test.php">./test</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
</phpunit>
|
7
postcss.config.js
Normal file
@@ -0,0 +1,7 @@
|
||||
module.exports = {
|
||||
plugins: [
|
||||
require('postcss-import'),
|
||||
require('postcss-simple-vars'),
|
||||
require('autoprefixer'),
|
||||
]
|
||||
}
|
22
src/App.php
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace Apprentice;
|
||||
|
||||
use Apprentice\Command;
|
||||
use Symfony\Component\Console\Application;
|
||||
|
||||
class App
|
||||
{
|
||||
/**
|
||||
* Runs cli application
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function main(): void
|
||||
{
|
||||
$cli = new Application;
|
||||
$cli->add(new Command\BuildCommand);
|
||||
$cli->add(new Command\ServerCommand);
|
||||
$cli->run();
|
||||
}
|
||||
}
|
104
src/Build.php
Normal file
@@ -0,0 +1,104 @@
|
||||
<?php
|
||||
|
||||
namespace Apprentice;
|
||||
|
||||
/**
|
||||
* Handles building pages in public folder
|
||||
* using configuration based on Page classes
|
||||
*/
|
||||
class Build
|
||||
{
|
||||
/**
|
||||
* Builds all pages in config
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function buildAll(): void
|
||||
{
|
||||
$this->cleanPublicFolder();
|
||||
|
||||
$pages = config('pages');
|
||||
foreach ($pages as $page) {
|
||||
$this->buildPage($page);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds single page in config
|
||||
*
|
||||
* @param string $name Name of page to build
|
||||
* @return string Contents of built page
|
||||
*/
|
||||
public function runSingleBuild(string $name): string
|
||||
{
|
||||
$pages = config('pages');
|
||||
|
||||
foreach ($pages as $page) {
|
||||
if ($page->name == $name) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->buildPage($page);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes all html files in public folder
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function cleanPublicFolder(): void
|
||||
{
|
||||
$files = glob(config('output_dir') . '/*.html');
|
||||
foreach ($files as $file) {
|
||||
unlink($file);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds single Page into html and
|
||||
* outputs to public directory
|
||||
*
|
||||
* @param Page $page Page from config to be built
|
||||
* @return void Contents of built page
|
||||
*/
|
||||
private function buildPage(Page $page): string
|
||||
{
|
||||
if (!empty($page->code)) {
|
||||
$code = file_get_contents(config('code_dir') . '/' . $page->code);
|
||||
$page->variables['code'] = $code;
|
||||
}
|
||||
|
||||
if ($page->template) {
|
||||
$template = config('templates_dir') . '/' . $page->template;
|
||||
} else {
|
||||
$template = config('templates_dir') . '/default.phtml';
|
||||
}
|
||||
$output = $this->getOutput($template, $page->variables);
|
||||
|
||||
file_put_contents(config('output_dir') . '/' . $page->name . '.html', $output);
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads template file with scoped
|
||||
* variables
|
||||
*
|
||||
* @param string $path Path to template in templates folder
|
||||
* @param array $vars Array of variables to be loaded in template
|
||||
* @return string Output of template
|
||||
*/
|
||||
private function getOutput(string $path, array $vars = []): string {
|
||||
if ($vars) {
|
||||
extract($vars);
|
||||
}
|
||||
|
||||
ob_start();
|
||||
require $path;
|
||||
$output = ob_get_contents();
|
||||
ob_end_clean();
|
||||
|
||||
return $output;
|
||||
}
|
||||
}
|
24
src/Command/BuildCommand.php
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace Apprentice\Command;
|
||||
|
||||
use Apprentice\Build;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
class BuildCommand extends Command
|
||||
{
|
||||
protected function configure()
|
||||
{
|
||||
$this->setName('build')
|
||||
->setDescription('Builds PHP templates into HTML files.')
|
||||
->setHelp('Help!');
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$build = new Build;
|
||||
$build->buildAll();
|
||||
}
|
||||
}
|
23
src/Command/ServerCommand.php
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace Apprentice\Command;
|
||||
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
class ServerCommand extends Command
|
||||
{
|
||||
protected function configure()
|
||||
{
|
||||
$this->setName('server')
|
||||
->setDescription('Runs PHP server that automatically builds files')
|
||||
->setHelp('Help!');
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$output->writeln('Starting development server on localhost:8080');
|
||||
system('php -S localhost:8080 -t docs src/util/router.php');
|
||||
}
|
||||
}
|
77
src/Page.php
Normal file
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
namespace Apprentice;
|
||||
|
||||
/**
|
||||
* A class representing a single page in the build process
|
||||
*/
|
||||
class Page
|
||||
{
|
||||
/**
|
||||
* Name of page, used in filename
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $name;
|
||||
|
||||
/**
|
||||
* Name of template to use
|
||||
* If none is provided, a default will be used
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
public $template;
|
||||
|
||||
/**
|
||||
* Name of code file to load as table
|
||||
* Will be skipped if none is provided
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
public $code;
|
||||
|
||||
/**
|
||||
* Map of data to passed to template
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $variables;
|
||||
|
||||
/**
|
||||
* Creates new page
|
||||
*
|
||||
* @param string $name
|
||||
* @param string|null $template
|
||||
* @param string|null $code
|
||||
* @param array $variables
|
||||
*/
|
||||
public function __construct(
|
||||
string $name,
|
||||
?string $template = null,
|
||||
?string $code = null,
|
||||
?array $variables = []
|
||||
) {
|
||||
$this->name = $name;
|
||||
$this->template = $template;
|
||||
$this->code = $code;
|
||||
$this->variables = $variables;
|
||||
}
|
||||
|
||||
/**
|
||||
* Static constructor
|
||||
*
|
||||
* @param string $name
|
||||
* @param string|null $template
|
||||
* @param string|null $code
|
||||
* @param array $variables
|
||||
* @return Apprentice\Page
|
||||
*/
|
||||
public static function create(
|
||||
string $name,
|
||||
?string $template = null,
|
||||
?string $code = null,
|
||||
?array $variables = []
|
||||
): Page {
|
||||
return new static($name, $template, $code, $variables);
|
||||
}
|
||||
}
|
149
src/util/functions.php
Normal file
@@ -0,0 +1,149 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Runs a scoped require on a partial
|
||||
*
|
||||
* The filename must start with an underscore
|
||||
* and end with .php or .phtml
|
||||
*
|
||||
* @param string $path Name of partial
|
||||
* @param array $vars Variables to use for the partial
|
||||
* @return void
|
||||
*/
|
||||
function partial(string $path, array $vars = []) {
|
||||
$dir = config('templates_dir');
|
||||
if (file_exists($dir. '/' . "_$path.php")) {
|
||||
$file = $dir. '/' . "_$path.php";
|
||||
} elseif (file_exists($dir . '/' . "_$path.phtml")) {
|
||||
$file = $dir. '/' . "_$path.phtml";
|
||||
} else {
|
||||
throw new Exception('Partial could not be found: ' . $dir . '/' . "_$path.php");
|
||||
}
|
||||
|
||||
extract($vars);
|
||||
|
||||
require $file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets url path to page
|
||||
*
|
||||
* @param string $page Name of page
|
||||
* @return string
|
||||
*/
|
||||
function page_path(string $page): string {
|
||||
return '/' . $page . '.html';
|
||||
}
|
||||
|
||||
/**
|
||||
* Safely escapes text for display in html
|
||||
*
|
||||
* @param string $text
|
||||
* @return string
|
||||
*/
|
||||
function escape(string $text): string {
|
||||
return htmlspecialchars($text, ENT_QUOTES, 'UTF-8', true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads content of svg icon from assets folder
|
||||
*
|
||||
* @param string $name Name of icon without extension
|
||||
* @return string Contents of file
|
||||
*/
|
||||
function icon(string $name): string {
|
||||
$dir = config('icon_dir');
|
||||
$path = $dir . '/' . $name . '.svg';
|
||||
if (file_exists($path)) {
|
||||
return file_get_contents($path);
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes string of PHP code and converts it into html for display
|
||||
*
|
||||
* @param string $code
|
||||
* @return string
|
||||
*/
|
||||
function code_table(string $code): string {
|
||||
$tokens = token_get_all($code);
|
||||
$output = '<div class="grid-code">' .
|
||||
'<div class="doc"></div>' .
|
||||
'<div class="code">' .
|
||||
'<pre>' .
|
||||
'<code class="language-php">';
|
||||
|
||||
$previousTokenWasComment = false;
|
||||
foreach ($tokens as $token) {
|
||||
if (is_string($token)) {
|
||||
$output .= $token;
|
||||
continue;
|
||||
}
|
||||
|
||||
$id = $token[0];
|
||||
$text = $token[1];
|
||||
|
||||
if ($id == T_COMMENT || $id == T_DOC_COMMENT) {
|
||||
$text = htmlspecialchars(trim(str_replace('/', '', $text)));
|
||||
|
||||
if ($previousTokenWasComment) {
|
||||
$output .= ' ' . $text;
|
||||
} else {
|
||||
$output .= '</code>' .
|
||||
'</pre>' .
|
||||
'</div>' .
|
||||
'<div class="doc">' .
|
||||
$text;
|
||||
}
|
||||
|
||||
$previousTokenWasComment = true;
|
||||
} else {
|
||||
if ($previousTokenWasComment) {
|
||||
$output .= '</div>' .
|
||||
'<div class="code">' .
|
||||
'<pre>' .
|
||||
'<code class="language-php">';
|
||||
}
|
||||
|
||||
$output .= htmlspecialchars($text);
|
||||
$previousTokenWasComment = false;
|
||||
}
|
||||
}
|
||||
|
||||
$output .= '</code>' .
|
||||
'</pre>' .
|
||||
'</div>' .
|
||||
'</div>';
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads config file into a global
|
||||
*
|
||||
* @param string $path
|
||||
* @return void
|
||||
*/
|
||||
function load_config(string $path) {
|
||||
$config = require $path;
|
||||
|
||||
if (!is_array($config)) {
|
||||
throw new \Exception('Config file does not return an array.');
|
||||
}
|
||||
|
||||
$GLOBALS['APPRENTICE_CONFIG'] = $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns config value
|
||||
*
|
||||
* @param string $key
|
||||
* @return mixed
|
||||
*/
|
||||
function config(string $key) {
|
||||
$config = $GLOBALS['APPRENTICE_CONFIG'] ?? [];
|
||||
|
||||
return $config[$key] ?? null;
|
||||
}
|
27
src/util/router.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
/**
|
||||
* Router file used for development server
|
||||
* to create html files on demand
|
||||
*/
|
||||
require __DIR__ . '/../../vendor/autoload.php';
|
||||
|
||||
load_config(__DIR__ . '/../../config.php');
|
||||
|
||||
$uri = $_SERVER['REQUEST_URI'];
|
||||
$pathinfo = pathinfo($uri);
|
||||
|
||||
if ($pathinfo['dirname'] == '/' && !isset($pathinfo['extension'])) {
|
||||
$pathinfo['extension'] = 'html';
|
||||
$pathinfo['filename'] = 'index';
|
||||
}
|
||||
|
||||
if ($pathinfo['extension'] == 'html') {
|
||||
$build = new Apprentice\Build;
|
||||
$output = $build->runSingleBuild($pathinfo['filename']);
|
||||
|
||||
echo $output;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
8
test/BaseTestCase.php
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace Test;
|
||||
|
||||
class BaseTestCase extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
|
||||
}
|
57
test/BuildTest.php
Normal file
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
namespace Test;
|
||||
|
||||
use Apprentice\Build;
|
||||
|
||||
class BuildTest extends BaseTestCase
|
||||
{
|
||||
public function setUp()
|
||||
{
|
||||
load_config(__DIR__ . '/static/config.php');
|
||||
mkdir('/tmp/apprentice_output');
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
$files = glob('/tmp/apprentice_output/*');
|
||||
foreach ($files as $file) {
|
||||
unlink($file);
|
||||
}
|
||||
|
||||
rmdir('/tmp/apprentice_output');
|
||||
}
|
||||
|
||||
public function test_build_single_page()
|
||||
{
|
||||
$build = new Build();
|
||||
|
||||
$build->runSingleBuild('test');
|
||||
|
||||
$html = file_get_contents('/tmp/apprentice_output/test.html');
|
||||
$expectedHtml = "<div>Test Title</div>\n" .
|
||||
"<div>Test Subtitle</div>\n" .
|
||||
"<div>Test Description</div>\n";
|
||||
|
||||
$this->assertFalse(empty($html));
|
||||
$this->assertEquals($expectedHtml, $html);
|
||||
}
|
||||
|
||||
public function test_build_all()
|
||||
{
|
||||
$build = new Build();
|
||||
|
||||
$build->buildAll();
|
||||
|
||||
$expectedHtml = "<div>Test Title</div>\n" .
|
||||
"<div>Test Subtitle</div>\n" .
|
||||
"<div>Test Description</div>\n";
|
||||
$expectedHtml2 = "<div>index</div>\n";
|
||||
|
||||
$html = file_get_contents('/tmp/apprentice_output/test.html');
|
||||
$html2 = file_get_contents('/tmp/apprentice_output/index.html');
|
||||
|
||||
$this->assertEquals($expectedHtml, $html);
|
||||
$this->assertEquals($expectedHtml2, $html2);
|
||||
}
|
||||
}
|
59
test/FunctionsTest.php
Normal file
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
namespace Test;
|
||||
|
||||
class FunctionsTest extends BaseTestCase
|
||||
{
|
||||
public function tearDown()
|
||||
{
|
||||
$GLOBALS['PARTIAL_TEST'] = null;
|
||||
}
|
||||
|
||||
public function test_load_config()
|
||||
{
|
||||
load_config(__DIR__ . '/static/config.php');
|
||||
|
||||
$this->assertEquals(__DIR__ . '/static/../icons', config('icon_dir'));
|
||||
}
|
||||
|
||||
public function test_page_path()
|
||||
{
|
||||
$page = page_path('home');
|
||||
|
||||
$this->assertEquals('/home.html', $page);
|
||||
}
|
||||
|
||||
public function test_escape()
|
||||
{
|
||||
$output = escape("'\"&");
|
||||
|
||||
$this->assertEquals("'"&", $output);
|
||||
}
|
||||
|
||||
public function test_icon()
|
||||
{
|
||||
load_config(__DIR__ . '/static/config.php');
|
||||
$icon = icon('test');
|
||||
|
||||
$this->assertFalse(empty($icon));
|
||||
$this->assertEquals("<test></test>\n", $icon);
|
||||
}
|
||||
|
||||
public function test_code_table()
|
||||
{
|
||||
$php = file_get_contents(__DIR__ . '/static/code_table.php');
|
||||
$expectedOutput = file_get_contents(__DIR__ . '/static/code_table.html');
|
||||
|
||||
$html = code_table($php);
|
||||
|
||||
$this->assertFalse(empty($html));
|
||||
$this->assertEquals($expectedOutput, $html . "\n");
|
||||
}
|
||||
|
||||
public function test_partial()
|
||||
{
|
||||
partial('partial', ['test' => 'test var']);
|
||||
|
||||
$this->assertEquals('test var', $GLOBALS['PARTIAL_TEST']);
|
||||
}
|
||||
}
|
1
test/icons/test.svg
Normal file
@@ -0,0 +1 @@
|
||||
<test></test>
|
4
test/static/code/test.php
Normal file
@@ -0,0 +1,4 @@
|
||||
<?php
|
||||
|
||||
// test comment
|
||||
$test = 'test';
|
4
test/static/code_table.html
Normal file
@@ -0,0 +1,4 @@
|
||||
<div class="grid-code"><div class="doc"></div><div class="code"><pre><code class="language-php"><?php
|
||||
|
||||
</code></pre></div><div class="doc">this is a test</div><div class="code"><pre><code class="language-php">$test = 'some test code';
|
||||
</code></pre></div></div>
|
4
test/static/code_table.php
Normal file
@@ -0,0 +1,4 @@
|
||||
<?php
|
||||
|
||||
// this is a test
|
||||
$test = 'some test code';
|
18
test/static/config.php
Normal file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
use Apprentice\Page;
|
||||
|
||||
return [
|
||||
'icon_dir' => __DIR__ . '/../icons',
|
||||
'code_dir' => __DIR__ . '/code',
|
||||
'templates_dir' => __DIR__ . '/templates',
|
||||
'output_dir' => '/tmp/apprentice_output',
|
||||
'pages' => [
|
||||
Page::create('index', 'index.phtml'),
|
||||
Page::create('test', null, 'test.php', [
|
||||
'title' => 'Test Title',
|
||||
'subtitle' => 'Test Subtitle',
|
||||
'description' => 'Test Description',
|
||||
]),
|
||||
],
|
||||
];
|
3
test/static/templates/_partial.phtml
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php
|
||||
|
||||
$GLOBALS['PARTIAL_TEST'] = $test;
|
3
test/static/templates/default.phtml
Normal file
@@ -0,0 +1,3 @@
|
||||
<div><?= escape($title) ?></div>
|
||||
<div><?= escape($subtitle) ?></div>
|
||||
<div><?= escape($description) ?></div>
|
1
test/static/templates/index.phtml
Normal file
@@ -0,0 +1 @@
|
||||
<div>index</div>
|
17
webpack.config.js
Normal file
@@ -0,0 +1,17 @@
|
||||
var Encore = require('@symfony/webpack-encore');
|
||||
|
||||
Encore
|
||||
.setOutputPath('docs')
|
||||
.setPublicPath('/')
|
||||
.addEntry('js/site', './assets/js/site.js')
|
||||
.addStyleEntry('css/site', './assets/css/site.css')
|
||||
.enablePostCssLoader()
|
||||
.configureBabel(function (babel) {
|
||||
babel.plugins.push(['prismjs', {
|
||||
"languages": ["php"],
|
||||
"css": false,
|
||||
}]);
|
||||
});
|
||||
;
|
||||
|
||||
module.exports = Encore.getWebpackConfig();
|