Академический Документы
Профессиональный Документы
Культура Документы
This is a Leanpub book. Leanpub empowers authors and publishers with the Lean Publishing
process. Lean Publishing is the act of publishing an in-progress ebook using lightweight tools
and many iterations to get reader feedback, pivot until you have the right book and build
traction once you do. This book is for sale at the following url:
https://leanpub.com/learnwebdevelopmentwithvegibit
Chapter 1: HTML
What Is HTML
We’re going to take a close look now at HTML5 and in order to do that, we have
to take a look at a little bit about what HTML is, where it comes from, and the
direction it is headed. HTML truly is the language of the web. I know we have
spoken about JavaScript being the language of the web, or PHP being the
language of the web. In fact, there are many languages of the web, but when it
comes right down to it, none of the others really matters if you do not have
HTML first. HTML is really the enabler of the World Wide Web. So let’s dig right
in and get our hands dirty with some HTML!
WHATWG
WHATWG stands for The Web Hypertext Application Technology Working Group. Say that
5 times fast! The purpose of this group is to standardize modern web frameworks like
HTML5. The history of this is that the W3C was working on XHTML 2.0 as a means of
making HTML a more strict markup language to work with application based websites.
XHTML was not popular with the web community, and HTML5 has become the go to
technology for modern web applications. HTML5 is really a bit of a loose term in that it
refers to a collection of technologies encompassing markup, design, and behavior. Think
HTML, CSS, and JavaScript to be more precise. At this stage of the game, we have the
WHATWG and W3C versions of HTML5 and they do not one hundred percent agree on
what the actual meaning of HTML 5 is. What they do agree on however, is the markup
portion of HTML5.
<html lang='en'>
<head>
<meta charset="UTF-8" />
<title>
Example HTML Document
</title>
<link rel="stylesheet" type="text/css" href="stylesheet.css" />
</head>
<body>
<h1>
This is some text inside of an H1 tag which is good for section titles.
</h1>
<p>
This text is part of a paragraph. This is good for many sentences grouped together by related
ideas.
</p>
</body>
</html>
This is about as simple as it gets, but it allows us to look at some of the key ideas with
regard to the markup in use. Let’s review them now.
• Doctype The doctype declaration is to tell the browser what version of HTML to
expect to parse within the document. I love this new doctype declaration in HTML5
because it is so simple unlike the clunky, attribute filled doctypes of the older
versions of HTML. <!doctype html> informs the browser that we are dealing with a
Standards Based Document.
• Comments We can see a comment included by the code <!– HTML5 Document
Structure –> Comments help developers to keep track of large complicated themes
that may be compiled out of many different files.
• Dom Tree Starting at <html lang=’en’> and ending with </html> is the Document
Object Model Tree. At the root of tree is the html tag itself. This is an example of a
container in HTML since it has both an opening and closing tag. Note that only
opening tags will have attributes, closing tags will never have attributes.
• Parent Child Relationships The concept of a container brings up the idea of Parent
and Children elements. Tags that are contained within another are children of their
parent. In this document the meta, title, and link tags are children of the head
element.
• Sibling Relationships When we think of Siblings, we think of equals. For example,
you and your brother or sister are siblings, and equal so to speak in the family tree.
In this HTML document, the head and body tags could be considered Siblings.
Tags and Containers
Tags are the basis of HTML and there are a few ways to write and interpret them.
Specifically, there are tags that create containers and those that do not. First up we’ll look
at the idea of a container tag. In our example HTML above, we have a title tag with both an
opening <title> and closing </title>. Between the tags is some text. The entire structure is
referred to as an element on that page, and since the opening and closing tags surround
the text it is also considered a container.
Meta tags on the other hand are en example of a non containing tag. A opening meta does
not need the equivalent closing meta. This is referred to as a standalone tag. Often times
you will see the format of auto ending the tag via a forward slash like so <meta
charset="UTF-8" /> This example has an attribute of charset and a value of UTF-8.
It may seem a bit mundane, but tags really are the basis of all that we do in web
development. It pays to understand them at a low level, in order to make higher level
problems easier to debug and troubleshoot later on.
• acronym
• bgsound
• dir
• frame
• frameset
• noframes
• isindex
• listing
• nextid
• noembed
• plaintext
• rb
• strike
• xmp
• basefont
• big
• blink
• center
• font
• marquee
• multicol
• nobr
• spacer
• tt
You may be wondering, why would they remove functionality from the language? Wouldn’t
I want to be able to accomplish just as much, and more with this great new HTML5? Well,
in reality, you can accomplish all the things these obsolete tags provide by using a
combination of supported HTML5 elements and additional CSS and or JavaScript. If you’re
trying to use the blink tag these days, you need to reevaluate your approach!
In addition to the obsolete elements, there is a large collection of obsolete attributes as
well. Let’s review them here
• abbr
• accept
• align
• alink
• archive
• axis
• background
• bgcolor
• border
• cellpadding
• cellspacing
• char
• charoff
• charset
• classid
• clear
• code
• codebase
• codetype
• color
• compact
• coords
• datafld
• dataformats
• datapagesize
• datasrc
• declare
• elements
• event
• for
• frame
• frameborder
• height
• hspace
• language
• link
• longdesc
• lowsrc
• marginbottom
• marginheight
• marginleft
• marginright
• margintop
• marginwidth
• methods
• name
• nohref
• noshade
• nowrap
• profile
• rev
• rules
• scheme
• scope
• scrolling
• shape
• size
• standby
• summary
• target
• text
• type
• urn
• usemap
• valign
• valuetype
• version
• vlink
• vspace
• width
Again, this just means that there are better ways to accomplish the same things. If you’ve
been developing web pages for a good period of time, you may be laughing as you look at
this collection of elements and attributes that have been deemed obsolete. Some of the
early WYSIWYG or What You See Is What You Get tools made abundant use of almost all
of these elements and attributes As they say, hindsight is 20 / 20.
Conclusion
I chose to really dig into HTML and HTML5 in this new series here at VegiBit because
there does seem to be a fair amount of confusion as to what HTML5 actually is. And you
know what, for good reason. The collection of standards and standards bodies governing
the future of the web, not to mention the influence billion dollar corporations have on how
things are being shaped, is enough to drive anyone mad. I once heard a saying about
HTML5: “Everyone is using it, nobody knows what it is!” Quite fitting in fact. This first jump
into the basics of HTML5 will get us going in the right direction to have a better
understanding of the tools we use everyday.
HTML has many fundamentals to be aware of. Whether we’re dealing with
HTML comments, HTML whitespace, Block Level elements, or inline elements,
there are several building blocks to memorize. Knowing these important key
concepts will pave the way for our HTML5 learning. Let’s jump right in!
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>
Fresh Style
</title>
<link rel="stylesheet" type="text/css" href="main.css" />
</head>
<body>
<h1>
Style Example
</h1>
<p>
This is a paragraph with some fresh style. It needs more than one sentence, so this is the second
sentence.
</p>
<p>
You can have more than one paragraph on a page. If you didn't know that, now you know.
</p>
<p>
One is the lonliest number, two is company, and three is a crowd. Guess which one this paragraph
is.
</p>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>
Fresh Style
</title>
<link rel="stylesheet" type="text/css" href="main.css" />
</head>
<body>
<h1>
Style Example
</h1>
<p>
This is a paragraph with some fresh style. It needs more than one sentence, so this is the second
sentence.
</p>
<p>
You can have more than one paragraph on a page. If you didn't know that, now you know.
</p>
<p>
One is the lonliest number, two is company, and three is a crowd. Guess which one this paragraph
is.
</p>
</body>
</html>
Both examples of HTML are telling the browser to do the same thing. It may not look like
that based on what the source looks like, but if we view this in the browser, we can see
both options give the same result.
You can be as sloppy as you want to! The browser will still recognize your chicken scratch
of HTML markup! Of course we don’t actually want to do this. As your webpages grow and
become more complicated, the nice formatting is going to pay big dividends to keeping
your sanity in check. Definitely try to keep your source code as neat and tidy as possible.
Comments are also whitespace when they are rendered in the browser. So if you add
several lines of comments to help with the meaning of your HTML source, it will be treated
as one space as the browser engine collapses multiple whitespace characters into one.
Using Paragraphs to Display Text
As you write several lines and sentences of content in your webpage, you will need a way
to organize the text into easy to read chunks. The best way to do this is to simply make
use of the paragraph or p elements on your page. In the example above, it was easy to
group together three different groups of text into three different paragraphs. Even though
you can easily place the text outside of the p tag, it is better to contain it within the
paragraph as it is much easier to style and format. To recap, paragraphs are created with
the p element, and then styled using css.
body, p {
line-height: 1;
font-family: Georgia, serif;
font-size: 16pt;
}
p, h1, h2, h3, h4, h5, h6, ol, ul, li { margin: 12pt; }
li { margin-left: 2em; }
h1 { font-size: 200%; }
h2 { font-size: 180%; }
h3 { font-size: 160%; }
h4 { font-size: 140%; }
h5 { font-size: 120%; }
h6 { font-size: 100%; }
We could also have placed this CSS inline, meaning in the same HTML page. Don’t do
this! You pretty much always want to put your CSS code into it’s own file and link to it via
the link tag. The link tag is a standalone tag, not a container, which has three attributes
that should be set. The first attribute is rel with a value of stylesheet, the second
is type with a value of text/css, and the third is the href with a value of main.css. The href
is a document relative file path, so if your CSS is in a different folder, simply include the
path to the folder in this attribute value. The CSS file may even be located somewhere in
the cloud via a CDN Content Delivery Network and if that is the case, just provide that file
path as well, it will still work.
Styling is going to come in very handy. If the CSS is removed from our example HTML, it is
quite bland indeed.
<base> Defines a default address or a default target for all links on a page
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>
Fresh Style
</title>
<link rel="stylesheet" type="text/css" href="main.css" />
<style>
p {
background-color: #E3E3E3;
}
</style>
</head>
<body>
<h1>
Style Example
</h1>
<p>
This is a paragraph with some fresh style. It needs more than one sentence, so this is the second
sentence.
</p>
<p>
You can have more than one paragraph on a page. If you didn't know that, now you know.
</p>
<p style="background-color:#D6E9C6">
One is the lonliest number, two is company, and three is a crowd. Guess which one this paragraph
is.
</p>
</body>
</html>
By applying a specific style to an element in the HTML page using the style tag in
the head tag of the document, you can see that the three paragraphs now have a
background color. For the third paragraph we applied a style inline on the element itself, so
in that case, it overrides anything in both the external style sheet and the style in the head
of the document. Awesome Stuff!
<html>
<head>
<title>
Including Javascript in HTML
</title>
<link rel="stylesheet" type="text/css" href="main.css" />
<script>
function count() {
var n = 0;
e = document.getElementById("counter");
setInterval(function () {
e.innerHTML = ++n;
}, 1000);
}
window.onload = count;
</script>
</head>
<body>
<h2>
Including Javascript in HTML
</h2>
<h3>
Watch this counter increment! <span id="counter">0</span>
</h3>
</body>
</html>
Your little JavaScript application is happily ticking along, displaying a number value to the
screen once every second. Another great resource for learning about HTML and
JavaScript together is the JavaScript Events Tutorial, do check it out!
The HTML Meta Tag
Metadata is data about data. Say Whay?! Sounds funny right? Well, it is actually very
useful. The meta tag give overview information about the current HTML page. The
metadata is not actually displayed on the visible page, but rather to give useful information
to the browser and search engines.
The common uses of meta elements are to specify keywords, page description, last
modified information, author of the page, and others.
Providing keywords for search engines
<meta name=”keywords” content=”HTML, CSS, PHP, HTML5, JavaScript”>
Give a description to the web page
<meta name=”description” content=”Free Web tutorials on PHP, JavaScript, HTML
and CSS”>
Define the author of the webpage
<meta name=”author” content=”Vegi Bit”>
Refresh the page every 25 seconds
<meta http-equiv=”refresh” content=”25″>
<html lang='en'>
<head>
<meta charset="UTF-8" />
<title>
HTML Text and Line Breaks
</title>
</head>
<body>
<h1>
HTML Text and Line Breaks
</h1>
<p>
This here is a lot of text. It is really random, but if you surely can't handle seeing another
bunch of lorem ipsum in to world. So in the sprit of our hot sauce, and Franks Red Hot and Bacon,
let's consider how tasty it really is. If you haven't had the Franks Red Hot, you will. By the powers
vested within something, it is so.
</p>
<p>
Effictive immediately, the campaign for the elimination of lorem ipsum has officially begun. If you
are caught using a lorem ipsum in your HTML demo, there will be repercussions. Repercussions of the
like, including, but not limited to, well... Some crazy stuff. Now eat that bacon.
</p>
</body>
</html>
In this small snippet of HTML here, we will view how the browser handles the flowing
poetry and observe where lines wrap. Once complete, we can insert a <br> tag after every
single period in the prose to see what happens. Observe Grasshopper.
<html lang='en'>
<head>
<meta charset="UTF-8" />
<title>
Get Your Phrase On
</title>
</head>
<body>
<h1>
Get Your Phrase On
</h1>
</div>
</body>
</html>
Yes, Yes it is my friend. As you can see here, this is bare bones display.
Hey that’s cool!
There’s nothing quite like the beauty of a piece of HTML being rendered in the browser
with absolutely no styling whatsoever. By using the phrase elements on HTML, we can
give meaning to elements, separate from the display of said elements. Now you can of
course style any of these elements to your hearts content, much the way the
awesome Twitter Bootstrap Framework does, but in this case we’re simply having a
friendly review of what’s available in bare bones HTML.
<html lang='en'>
<head>
<meta charset="UTF-8" />
<title>
Controlling The Font
</title>
</head>
<body>
<h1>
Controlling The Font
</h1>
</div>
</body>
</html>
So there you go, you can see we have several interesting and meaningful ways to markup
the font on the webpage when needed.
<html lang='en'>
<head>
<meta charset="UTF-8" />
<title>
Using Headings In Your Webpage!
</title>
</head>
<body>
<h1>
Using Headings In Your Webpage!
</h1>
</div>
</body>
</html>
By using the different headings correctly, you’ll be sure that the webpage follows a useful
outline or hierarchy. Again, this structure helps both the reader and the search engines to
properly digest your content to its max.
<html lang='en'>
<head>
<meta charset="UTF-8" />
<title>
Quote Marks and Quotations in HTML
</title>
</head>
<body>
<h1>
Quote Marks and Quotations in HTML
</h1>
<p>
Bacon has been found to be a beneficial addition to the diet of all people <q>in the whole
world.</q> This is in now way an endorsement for you to eat more bacon.
</p>
<blockquote>
Eat Bacon on an as needed Happiness Basis!
</blockquote>
</body>
</html>
<html lang='en'>
<head>
<meta charset="UTF-8" />
<title>
Preformatted Text Rocks
</title>
</head>
<body>
Way
('>
/))@@@@@.
/@"@@@@@()@
.@@()@@()@@@@
@@@O@@@@()@@@
@()@@@@@()@@
@()@||@@@@@'
'@@||@@@'
||
||
||
||
^^^^^^^^^^^^^^^^^^^^^^^
</body>
</html>
List Types in HTML
HTML provides nice ways to present content in lists. In this example we’ll take a look at
Ordered Lists, Unordered Lists, as well as the under used Definition List.
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset="UTF-8" />
<title>
List Types in HTML
</title>
</head>
<body>
<h1>
List Types in HTML
</h1>
<ol>
<li>This is the first li</li>
<li>This is the second li</li>
<li>This is the third li</li>
</ol>
<ul>
<li>I'm unordered!</li>
<li>So am I!</li>
<li>You guessed it!</li>
</ul>
<dl>
<dt>HTML</dt>
<dd>A Markup Language for presenting content on the world wide web.</dd>
<dt>PHP</dt>
<dd>A Fantastic scripting language that provides dynamic websites and runs on the server.</dd>
<dt>CSS</dt>
<dd>Used to apply style to HTML elements.</dd>
<dt>JavaScript</dt>
<dd><s>The religion of Douglas Crockford</s> Used to add interactivity and behavior to static web
pages.</dd>
</dl>
</body>
</html>
We can look at how these elements display in the browser here. Again, this is bare bones
HTML, so the presentation is a bit bland. Out in the wild, most web designers will use CSS
to make list elements look super slick. Often times, the list elements are simply used as
organizational elements, and the CSS applied to them hides their actual list like nature.
Controlling Text Direction in HTML
Though there probably isn’t a huge need for controlling the text direction when using
English in your website, it can be useful for other languages such as Hebrew. In this case,
text is actually written left to right. Confusing if you ask me! By setting the bdo tag, or
bidirectional override, the text will then appear reversed in the page. Let’s check out the
results when applying this to some existing HTML.
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset="UTF-8" />
<title>
Controlling Text Direction in HTML
</title>
</head>
<body>
<h1>
Controlling Text Direction in HTML
</h1>
<p>
<bdo dir="rtl">This here is a lot of text. It is really random, but if you surely can't handle
seeing another bunch of lorem ipsum in to world. So in the sprit of our hot sauce, and Franks Red Hot
and Bacon, let's consider how tasty it really is. If you haven't had the Franks Red Hot, you will. By
the powers vested within something, it is so.</bdo>
</p>
<p dir="rtl">
Effective immediately, the campaign for the elimination of lorem ipsum has officially begun. If you
are caught using a lorem ipsum in your HTML demo, there will be repercussions. Repercussions of the
like, including, but not limited to, well... Some crazy stuff. Now eat that bacon.
</p>
</body>
</html>
Word Break Suggestion
There may be times when you would like to control how a long string of text wraps in the
page. You can do this with soft hypens or the <wbr> tag. The difference is that the soft
hypen ­ will break the string and add a hyphen at the break point. The <wbr> tag
breaks the word at the specified point, without adding a hypen. You can test this in your
HTML and see the result.
Ruby Characters
Ruby is a super popular programming language with widespread acceptance due to the
Ruby on Rails framework. This Ruby however, is not referring to the programming
language. In this instance, Ruby Characters are referring to annotations which show
pronunciation. HTML has a <ruby> tag to allow you to make use of these annotations in
your web page.
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset="UTF-8" />
<title>
Ruby Characters
</title>
</head>
<h1>
Ruby Characters
</h1>
<p>
The two ideograph symbols in this Japanese text has a hiragana annotation.
</p>
<p lang="ja" style="margin: 100px; font-size: 200%">
<ruby>
漢
<rp>(</rp>
<rt>かん</rt>
<rp>)</rp>
字
<rp>(</rp>
<rt>じ</rt>
<rp>)</rp>
</ruby>
</p>
<p>
This instance is written in simplified Chinese and the pinyin is the annotation here.
</p>
</body>
</html>
Working With HTML Images
The HTML image tag is an inline element however there will be instances when
flowing text around an image is desired. In fact, this happens all the time. If
you’ve worked with images in HTML, you’ll know that at times it seems like the
image has a mind of its own in regard to where and how it gets displayed on the
page in relation to text. Let’s take a closer look at embedding images in our
webpages, and how to format them so that images and text can live in
harmony. In fact, in looking at the opening text of this tutorial, we are using one
of the very techniques we will discuss. Let’s begin!
First we’ll need to whip up some HTML with an image so that we can complete some tests.
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset="UTF-8" />
<title>Working With HTML Images</title>
</head>
<body>
<h1> Working With HTML Images </h1>
<p>Web Developers use HTML to build websites for the Internet. The Internet is also known as the
World Wide Web. HTML is not the only technology in use however. You may also run across CSS,
JavaScript, Ruby, PHP, and SQL. All of these pieces of the puzzle fit together to create something of
value. It is fun to read text, yes it is.</p>
<p>You may like chicken. Your friend may prefer only fresh fruits and vegetables. Leafy Greens are
likely the best bet for you. The other day, I had a delicious lunch at an Italian restaraunt. Have
you had yourself a nice bowl of Pasta lately with some nice red sauce? I'm sure you have, but if you
have not, it is important that you do.</p>
<p>If it comes to your attention, you'll notice this is nothing more than gibberish. Due to the war
on lorem ipsum, nonsense text has become the defacto standard for working with agile mockup tutorial
text snippets. Focusing on the low hanging fruit will yield dividends in the same space of time. Yes
if you must, you can do just that. Have a great day!</p>
</body>
</html>
As you can see, there is nothing special about this snippet of HTML. Of course if you read
the sample text, you may be enlightened by a few of the words of wisdom provided, but
beyond that – this is pretty simple stuff. This is a basic HTML Web Page which supports
HTML5 based on the doctype, it has some basic head information, an h1, an image, and a
few paragraphs. We can view it in the browser and it displays as you see here.
The image is all by itself, but not because it is block level. The paragraph begins after the
image tag, so the text starts at that point. How about if we’d like to have the text flow
around the image instead. We can do this with CSS. For brevity, we’ll just put the style
rules right in the head of the document. The following code will now be inserted.
<style>
img {
float:left;
}
</style>
That looks a little better. By applying the css float property to the image tag, we
There we go!
can control how text flows around an image. It looks ok, but it feels a little cramped. The
text is smacked right up against the image. Let’s give the layout a little breathing room. By
adding some margin values to the CSS like so
<style>
img {
float:left;
margin-right: 50px;
margin-bottom: 10px;
}
</style>
We’ll notice that the text now has plenty of space between itself and the HTML5 logo. This
looks a little better.
Just as we can float an image left, floating the image right is just as easy. We’ll float left,
and also change the margin-right to margin-left so that it looks uniform. With the new code
of
<style>
img {
float:right;
margin-left: 50px;
margin-bottom: 10px;
}
</style>
The page will now look like this.
That looks pretty good. Understanding how to float text around your images is going to
reduce your frustration levels twenty fold, trust me!
One thing to note about assigning the float property to images is that it converts the
element from inline to block level. This will have an impact on other CSS design that may
be applied to the element.
Now, you would think that these two elements would stack on top of each other by looking
at the source code. What happens in the web page when we load it in the browser is a little
different though. This is the result so far.
you say. Maybe you didn’t quite expect the images to display side by
Hey that looks really good!
side, but hey, you’re of the easy going variety and it looks acceptable so good enough,
right? Well, it’s all good except for one problem. Your picky client keeps talking about their
competitor and how great their stacked images look on their marketing page. He feels so
attached to this stacking look, that he has decided that you don’t get paid until images
stack. What’s a friendly Web Developer to do? Well, in this case, the clear property may be
just what the doctor ordered. Let’s add it to our CSS markup like so.
<style>
img {
float:right;
clear: right;
margin-left: 50px;
margin-bottom: 10px;
}
</style>
Boo Yeah!! One word: Stacked. Good work Grasshopper.
<html lang='en'>
<head>
<meta charset="UTF-8" />
<title>
HTML Floats - Break it Down
</title>
<style>
img.float-right {
float: right;
margin-left: 12px;
margin-bottom: 7px;
border: solid blue 1px;
padding: 3px;
}
.clear {
clear: both;
}
</style>
</head>
<body>
<h1>
HTML Images
</h1>
</body>
</html>
Cool! This looks pretty good. Now let’s consider the second paragraph where we have
finished dinner, and moved on to dessert. Perhaps we’d like that second paragraph to
begin after the image. Let’s see how to do that. We’ll make use again of the CSS property
clear which is used to clear floating objects like an image. You can specify a value for clear
of right, left, or both. In this example, by adding this css
#hack {
clear: right;
}
Have a play around with the other clear options to see how they work in your web pages.
You’ll love the control the clear property is able to provide when dealing with floating
elements on the page.
<body>
<img src="images/imagemaps.jpg" width="400" height="300" usemap="#imagemap">
<map name="imagemap">
<area shape="rect" coords="6,39,126,137" href="http://vegibit.com/what-is-html/" alt="what is
html">
<area shape="rect" coords="136,40,249,140" href="http://vegibit.com/digging-in-to-html-
fundamentals/" alt="html fundamentals">
<area shape="circle" coords="316,96,55" href="http://vegibit.com/the-top-11-most-important-html-
text-features-to-review/" alt="html text features">
<area shape="rect" coords="383,46,485,145" href="http://vegibit.com/getting-started-with-
javascript-programming/" alt="get started with javascript">
<area shape="rect" coords="17,174,126,273" href="http://vegibit.com/javascript-code-structure/"
alt="javascript code structure">
<area shape="rect" coords="141,172,245,274" href="http://vegibit.com/javascript-functions-
tutorial/" alt="javascript functions">
<area shape="circle" coords="320,215,59" href="http://vegibit.com/javascript-events-tutorial/"
alt="javascript events">
<area shape="rect" coords="384,165,486,276" href="http://vegibit.com/document-object-model-
tutorial/" alt="document object tutorial">
</map>
</body>
</html>
<html lang='en'>
<head>
<meta charset="UTF-8" />
<title>
Creating HTML Hyperlinks
</title>
</head>
<body>
<h1>
Creating HTML Hyperlinks
</h1>
<p>
It's easy to create links. We can link to Google if we'd like to complete a search!
<a href="http://www.google.com">Google</a>. Very easy!
</p>
</body>
</html>
You can copy the HTML source into your own HTML file, and you will now have a nice link
to Google so you can search the Internet. The hyperlink itself is created using the anchor
or a tag. There are a few attributes you can set but in this example all we are concerned
with is the href attribute. The value you specify inside the href attribute tells the a tag
where to send a user when she click on the link in the page.
The a tag is pretty flexible and you can use it in many ways. An interesting property of
the a tag is that it allows block level content inside of the element. Recall, block level
elements take up vertical space. Certainly text links are the most common use case of
using the a tag but we can also wrap the a tag around any sized image, or even a div
which may be taking up large amounts of vertical space. The provides a much larger
clickable surface area if you need to provide that for your users.
<html lang='en'>
<head>
<meta charset="UTF-8" />
<title>
Relative HTML Hyperlinks
</title>
</head>
<body>
<h1>
Relative HTML Hyperlinks
</h1>
<p>
We can use relative URLs to link to other resources in the same domain.
<a href="directory/hyperlinks.html">This is a relative URL!</a>
</p>
</body>
</html>
hyperlinks.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>
This page is in a directory
</title>
</head>
<body>
<h1>
A webpage
</h1>
<p>
I'm located in the directory folder
</p>
<p>
We can link back to the original document like so. <a href="../webpage.html">Link Back!</a>
</p>
</body>
</html>
This simple code will set up links between two HTML files located in different directories
using a Relative URL format. We have a link on each page to show how you can navigate
both up and down the directory structure. When you want to navigate up, you simple
provide the name of the directory followed by a forward slash, followed by the name of the
file to link to. If you need to span multiple directories, that is easy to do as well. You simply
specify them in this format. directory/otherdirectory/hyperlinks.html. When you need
to navigate down the directory path, you can use the special ../ notation to go back one
level. If you need to span multiple directories while going back you can do so by doing
something like this ../../webpage.html.
<html lang='en'>
<head>
<meta charset="UTF-8" />
<base href="http://shell.cas.usf.edu/mccook/uwy/" />
<title>
Relative HTML Hyperlinks
</title>
</head>
<body>
<h1>
Relative HTML Hyperlinks
</h1>
<p>
Changing what the HTML will use for Relative URL Calculations can be done with the base tag.
</body>
</html>
In this code, even though we only specified the href in the a tag as hyperlinks.html, if we
click the link, we are taken to the URL
of http://shell.cas.usf.edu/mccook/uwy/hyperlinks.html. Wow! This was possible since
we specified the base of http://shell.cas.usf.edu/mccook/uwy/ in the <base> tag. This is
a very powerful feature, but seldom used in popular web development. The reasons is that
it can lead to confusion and problems in maintaining the code as new pages are added to
your website.
Another popular use of this technique is to provide a fragment that the user can click at
various places in the web page to bring them back to the top of the page. It uses the same
technique. You simply place an id on an element near the top of the page, then provide a
link somewhere else that uses that id as its href value, and when the user clicks – they will
go right to the top of the page. Fun!
<a href="http://vegibit.com/getting-started-with-javascript-programming/"><img
src="http://vegibit.com/wp-content/uploads/2014/04/javascript.png" /></a>
Text Link
Learn HTML
Image Link
Text Link
Learn JavaScript
Image Link
Conclusion
Links are so common in our everyday use that we rarely even think twice about them. It
was fun to review all of the fundamentals of HTML Hyperlinks in this episode. In fact,
revisiting the page jump with fragments concept has me thinking I should implement that
technique more often!
HTML5 data attributes are supported in all the modern web browsers including Google
Chrome, Mozilla Firefox, and Apple Safari. Both JavaScript and jQuery work equally well
with data attributes. With these key concepts in mind, let’s take a look at some simple
markup that will show these ideas in action.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>
Working With HTML5 data attributes
</title>
<link href="css/bootstrap.min.css" rel="stylesheet">
<script src="jquery-1.11.1.js"></script>
<script src="js/bootstrap.min.js"></script>
<script>
$(document).ready(function () {
});
<body class="container">
<h1>
Working With HTML5 data attributes
</h1>
<p class="lead">
You can specify your own data attributes on your tags in the page. This is super useful for placing
data dynamically into the HTML via a server side technology, then accessing those values by grabbing
them with JavaScript.
</p>
<a class="btn btn-primary btn-lg btn-block" href="#" data-my-attribute="BOOM!">Click, Click</a>.
<div id="content"></div>
<button class="btn btn-success btn-lg btn-block" data-video-game="Super Mario Brothers " data-game-
status="is the greatest " data-game-time-frame="of all time!" onclick="answer(this)">
Click to Learn the Greatest Video Game of All Time!
</button>
<div id="native"></div>
</body>
</html>
Cool!This was a super simple nonsense example, but it gets the point across. For the first
example, we have a button on the page, with some jQuery set up that will act when the
button is clicked. When we click the button, jQuery fetches the value of the data attribute in
question and places that value into the myAttribute variable. Then using jQuery, we simply
insert a snippet of HTML after the empty content div in the HTML and include the value
of myAttribute in the output.
For the second example we use native JavaScript to accomplish a similar effect. This
example shows how multiple data attributes assigned to the same element are handled.
Basically, all of the various data attributes get auto converted to camel case and placed
into the dataset object. In the HTML, we simply attach an onclick event and run the
function answer when the user clicks to find out what the greatest video game of all time is.
Inside our function we set up three variables and assign their values using the data we
were able to access from the three different data attributes that were a part of the element
on the page. We then use native DOM functions to assemble a new element and manually
append the element to the div on the page. Thanks goodness for jQuery
</form>
We would take a look at how this renders in the browser, but the form itself is actually not
displayed in the browser. It is only the elements within the form that display, and we’ll take
a look at some of them now.
<input type="text">
Text fields for input are used to give the user a one line field to enter text. They are quite
common, and this is an example of the syntax to create one.
<form>
Website: <input type="text" name="website"><br>
Computer: <input type="text" name="computer">
</form>
<input type="password">
An input can also have a type of password. This input essentially works the same as
type text, but the browser will obscure the input text by making the characters you type
invisible by turning them into small circles or asterisks. In addition, when you submit the
form, the browser will usually ask you if you would like to have your password
remembered. This is all due to setting the type to password. This is some HTML that
denotes an input with it’s type set to password.
<form>
Password: <input type="password" name="password">
</form>
<input type="checkbox">
The checkbox seems simple enough. Then you learn about Radio Buttons There is
sometimes some confusion between the two, since they both look pretty similar in the
browser with the exception that checkboxes come in the shape of a small box, while radio
buttons look more like a small circle. Each of them share the trait of being able to be
selected by the user. They seem so alike, so what gives?! The main idea is
that checkboxes are used for one or many choices. Say you provided a list of four
seasons to the user. With the checkbox option, the user could select just one, or all of the
seasons. With the radio button option, the user would only be able to select her favorite.
The HTML looks like this.
<form>
<input type="checkbox" name="season" value="spring"> Spring<br>
<input type="checkbox" name="season" value="summer"> Summer<br>
<input type="checkbox" name="season" value="fall"> Fall<br>
<input type="checkbox" name="season" value="winter"> Winter
</form>
<input type="radio">
Now that you see how checkboxes work, it is the perfect time to observe how Radio
Buttons work! Like we explained above, a collection of checkboxes provides the user the
ability to select one or many options. The radio button is different in that the user can only
select one. We can redo the above HTML and simply change the type to radio. Observe.
<form>
<input type="radio" name="season" value="spring"> Spring<br>
<input type="radio" name="season" value="summer"> Summer<br>
<input type="radio" name="season" value="fall"> Fall<br>
<input type="radio" name="season" value="winter"> Winter
</form>
<select>
The <select> tag is used to provide a drop down list to the user. Inside of
the <select> tag, you place <option> tags to contain each different possible selection.
The <select> tag is a single choice selection scenario by default. You can change this to a
multiple selection by adding [] brackets to the end of the name attribute and setting the
multiple attribute. You can hold down the Ctrl in windows and the Command button on a
Mac in order to select more than one option.
<form>
<select name="select2[]" multiple="multiple">
<option>Chinese</option>
<option>Mexican</option>
<option>Italian</option>
<option>Thai</option>
<option>Seafood</option>
<option>Indian</option>
<option>Mediterranean</option>
</select>
</form>
Chinese
<datalist>
The <datalist> tag is pretty slick in that it provides a type of auto complete functionality as
the user begins to type. The auto completion is done by checking what the user types
against all of the values provided for each option. The closest match will auto populate
when the user begins typing. The list attribute of the associated input element is what
binds the datalist and input together.
<input name="days" list="days">
<datalist id="days">
<option value="Sunday">
<option value="Monday">
<option value="Tuesday">
<option value="Wednesday">
<option value="Thursday">
<option value="Friday">
<option value="Saturday">
</datalist>
<input type="submit">
The Mac Daddy, The Big KaHuna, The Stud to rule them all – it is our trusty <input
type="submit"> button. At the completion of your form, you are going to need a way to
actually take all of the collected data and send it on over to the server for some
processing. You do this of course with the Submit Button. When the user clicks the Submit
Button in your form, the data which was collected will be sent to a specific server side page
based on the action attribute which was set in the opening <form> tag. This data can be
passed via GET or POST. We’re focusing on POST in this episode. There are countless ways
to style the submit button, but the actual HTML to enable this to happen looks something
like this:
<form name="input" action="process.php" method="post">
Website: <input type="text" name="website">
<input type="submit" value="Submit">
</form>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Using HTML Forms For Data Collection</title>
<link rel="stylesheet" type="text/css" href="css/bootstrap.min.css" />
<script src="jquery-1.11.1.js"></script>
<script>
$(document).on('submit', 'form.form-horizontal', function () {
$.ajax({
url: $(this).attr('action'),
type: $(this).attr('method'),
data: $('form').serialize(),
success: function (data) {
$('#results').append(data);
},
error: function (xhr, err) {
alert('Error');
}
});
return false;
});
</script>
</head>
<body class="container">
<div id="form">
<h2> Using HTML Forms For Data Collection <small>Any element you want to collect data from in a
form must have a <code>name</code> property. The <code>name</code> becomes the key name of the
associative array once the form is submitted.</small></h2>
<form class="form-horizontal" action="print_r_post.php" method="post">
<fieldset>
<div class="form-group">
<div class="col-xs-12">
<input name="textinput1" class="form-control" id="inputEmail" placeholder="Email" type="text">
<span><strong><input></strong> of type <code>text</code></span>
</div>
</div>
<div class="form-group">
<div class="col-xs-12">
<input name="textinput2" pwfprops="," class="form-control" id="inputPassword"
placeholder="Password" type="password">
<span><strong><input></strong> of type <code>password</code></span>
<div class="checkbox">
<input name="checkbox1" type="checkbox">
<span><strong><input></strong> of type <code>checkbox</code></span>
</div>
<div class="checkbox">
<input name="checkbox2" type="checkbox">
<span><strong><input></strong> of type <code>checkbox</code></span>
</div>
</div>
</div>
<div class="form-group">
<div class="col-xs-12">
<textarea name="textarea" class="form-control" rows="3" id="textArea"></textarea>
<span><strong><textarea></strong> is not an <strong><input></strong> and has no type</span>
</div>
</div>
<div class="form-group">
<div class="col-xs-12">
<div class="radio">
<input name="radioOptions" id="optionsRadios1" value="option1" type="radio">
<span><strong><input></strong> of type <code>radio</code></span>
</div>
<div class="radio">
<input name="radioOptions" id="optionsRadios2" value="option2" type="radio">
<span><strong><input></strong> of type <code>radio</code></span>
</div>
</div>
</div>
<div class="form-group">
<div class="col-xs-12">
<select name="select1" class="form-control">
<option>Jordan</option>
<option>James</option>
<option>Bird</option>
</select>
<strong><select></strong> is not an <strong><input></strong> and has no type
<br>
</div>
</div>
<div class="form-group">
<div class="col-xs-12">
<input name="days" class="form-control" list="days">
<datalist id="days">
<option value="Sunday">
<option value="Monday">
<option value="Tuesday">
<option value="Wednesday">
<option value="Thursday">
<option value="Friday">
<option value="Saturday">
</datalist>
<strong><datalist></strong> provides autocomplete as you begin typing
</div>
</div>
<div class="form-group">
<div class="col-xs-12">
<button type="submit" class="btn btn-primary btn-block">Submit</button>
</div>
</div>
</fieldset>
</form>
</div>
</body>
</html>
print_r_post.php
<pre class="bg-info">
<h3>
<?php
print_r($_POST);
?>
This is an example of Rick James filling out all of the information in our form. Dealing with
the server side processing of all of this data is beyond the scope of this episode, but a
good thing to include here is an example of being able to view the raw data that gets
submitted. We use just a small piece of JavaScript to do this by sending the data via AJAX
to the print_r_post.php file on the server using jQuery. This PHP file does nothing more
than to print recursively all of the data that gets sent to it. That data then gets inserted into
the page, again using jQuery. The code to make it happen is right here.
$(document).on('submit', 'form.form-horizontal', function () {
$.ajax({
url: $(this).attr('action'),
type: $(this).attr('method'),
data: $('form').serialize(),
success: function (data) {
$('#results').append(data);
},
error: function (xhr, err) {
alert('Error');
}
});
return false;
});
You can run this code in your own local development environment as well. The output
when we click the submit button here should result in the following getting inserted into the
page.
Awesome!Being able to dump this form data to an array makes it easy to troubleshoot and
debug any form problems you may run across during your web development
adventures
As an added bonus, now that you are a pro in creating awesome forms in HTML, you can
also read up on PHP Form Processing so that you can do whatever you like with the data
you are able to collect!
HTML Encoding With htmlspecialchars and
htmlentities
In the last episode of this PHP Tutorial Compilation, we looked at working with
Links and URLs and how sometimes, special characters will wreak havoc upon
our HTML. These problems can at least break a link, or at worst, expose a
vulnerability to malicious intent via the goblins of the internets which wish to
bring malice to your web application. It turns out, it is not only our URLs that we
must protect and encode. We also need to be aware of the large collection of
special characters that may appear in the text of your HTML. For this, we also
have convenient ways to encode and protect our markup so as to be sure your
website remains upright, intact, working smoothly, and most of all being the
awesome presence that it is. Let’s do this!
Character Encoding
< <
> >
& &
" "
What this means is that when you would like your users to see the literal character, you
need to provide the coded version. Maybe you would like to say something like Twitter is
greater than Facebook, and use the greater than sign. In the actual html will be Twitter is
> Facebook, however the user will see the actual Twitter is > Facebook displayed. If
this or any of the other reserved characters are not properly encoded, you run the risk of
causing your page to not display to the user.
htmlspecialchars($string)
First up we’ll examine the use of htmlspecialchars. It might make sense to observe a
broken scenario, and then we’ll look at the solution using htmlspecialchars. Suppose we
want to include a link with specific anchor text. The anchor text we’d like to display
is <Click Here> & Prosper! So you figure, ok easy enough, we can just place this text we
like in between anchor tags and create our link. Let’s try it.
<html>
<head>
<meta charset="utf-8">
<title>HTML Encode Like a PRO</title>
<link href="css/bootstrap.min.css" rel="stylesheet">
<script src="js/respond.js"></script>
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script src="js/bootstrap.min.js"></script>
</head>
<body>
<a href="http://localhost/bootstrapsandbox/encode.php">
<Click Here> & Prosper!
</a>
</body>
</html>
& Prosper!
Do you see what that is right there? That right there, is a bit fat fail. The page didn’t display
the text we wanted at all. The reason for this is because the browser comes along and
sees those angled brackets and thinks that it is dealing with an HTML tag. In this case
however, it is not HTML at all. It is the actual angled brackets that we want the user to see
in the text of the link. It is times like this that htmlspecialchars comes to the rescue!
Observe!
<html>
<head>
<meta charset="utf-8">
<title>HTML Encode Like a PRO</title>
<link href="css/bootstrap.min.css" rel="stylesheet">
<script src="js/respond.js"></script>
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script src="js/bootstrap.min.js"></script>
</head>
<body>
<a href="http://localhost/bootstrapsandbox/encode.php">
<?php echo htmlspecialchars('<Click Here> & Prosper!'); ?>
</a>
</body>
</html>
<Click Here> & Prosper!
Nice!Now that link text is working as designed. Think of the htmlspecialchars as a method
to disable HTML so to speak. It disables the HTML to the browser and allows the user to
see what the browser normally sees. A key point of note is that htmlspecialchars only
handles the four reserved characters listed in the table above. Now you may know that
there are a rather large collection of symbols that we might want to display in the text of
our HTML which the browser will not know how to render. Things like Trademark symbols,
Copyright Symbols, At signs, and many more. In this case, you need to bust out the big
dog, the htmlentities function.
htmlentities($string)
The htmlentities function covers all characters that have an equivalent html entity
representation in the language. Therefore, htmlentities is much more powerful. To illustrate
this, we’ll try to enter in some of the more common special characters that you might want
to have in your webpage. Let’s try it out.
<?php
$text = '© ® ™ £ € ¥';
echo $text;
?>
This might display on some devices, however you may get just a string of really strange
hieroglyphic looking type characters. To be safe, you should wrap any text that has special
characters into the htmlentities function like so.
<?php
$text = '© ® ™ £ € ¥';
echo htmlentities($text);
?>
©®™£€¥
<body>
<?php
$page = 'bootstrapsandbox/encode.php';
$variable1 = 'Look out now, < > " and & which are bad!';
$variable2 = 'More bad chars like &#?*$[]+ and so on!';
$anchortext = '<Click Here> & Prosper!';
$url = 'http://localhost/';
// Just becuase a string is now fully URL encoded does not mean
// it is safe for output into page HTML. This is why the $url
// parameter must also be run through htmlspecialchars.
?>
<a href="<?php echo htmlspecialchars($url); // ?>">
<?php echo htmlspecialchars($anchortext); ?>
</a>
</body>
</html>
http://localhost/bootstrapsandbox%2Fencode.php?variable1=Look+out+now%2C+%3C+%3E+%22+and+%26+which+
are+bad%21&variable2=More+bad+chars+like+%26%23%3F%2A%24%5B%5D%2B+and+so+on%21
The result is a nicely encode URL with and special characters or entities accounted for
which is epic!
Á Á
 Â
à Ã
Ä Ä
Å Å
Æ Æ
Ç Ç
È È
É É
Ê Ê
Ë Ë
Ì Ì
Í Í
Î Î
Ï Ï
Ð Ð
Ñ Ñ
Ò Ò
Ó Ó
Ô Ô
Õ Õ
Ö Ö
Ø Ø
Ù Ù
Ú Ú
Û Û
Ü Ü
Ý Ý
Þ Þ
ß ß
à à
á á
â â
ã ã
ä ä
å å
æ æ
ç ç
è è
é é
ê ê
ë ë
ì ì
í í
î î
ï ï
ð ð
ñ ñ
ò ò
ó ó
ô ô
õ õ
ö ö
ø ø
ù ù
ú ú
û û
ü ü
ý ý
þ þ
ÿ ÿ
Symbol Encoding
¡ ¡
¢ ¢
£ £
¤ ¤
¥ ¥
¦ ¦
§ §
¨ ¨
© ©
ª ª
« «
¬ ¬
­
® ®
¯ ¯
° °
± ±
² ²
³ ³
´ ´
µ µ
¶ ¶
¸ ¸
¹ ¹
º º
» »
¼ ¼
½ ½
¾ ¾
¿ ¿
× ×
÷ ÷
Symbol Encoding
∀ ∀
∂ ∂
∃ ∃
∅ ∅
∇ ∇
∈ ∈
∉ ∉
∋ ∋
∏ ∏
∑ ∑
− −
∗ ∗
√ √
∝ ∝
∞ ∞
∠ ∠
∧ ∧
∨ ∨
∩ ∩
∪ ∪
∫ ∫
∴ ∴
∼ ∼
≅ ≅
≈ ≈
≠ ≠
≡ ≡
≤ ≤
≥ ≥
⊂ ⊂
⊃ ⊃
⊄ ⊄
⊆ ⊆
⊇ ⊇
⊕ ⊕
⊗ ⊗
⊥ ⊥
⋅ ⋅
Β Β
Γ Γ
Δ Δ
Ε Ε
Ζ Ζ
Η Η
Θ Θ
Ι Ι
Κ Κ
Λ Λ
Μ Μ
Ν Ν
Ξ Ξ
Ο Ο
Π Π
Ρ Ρ
Σ Σ
Τ Τ
Υ Υ
Φ Φ
Χ Χ
Ψ Ψ
Ω Ω
α α
β β
γ γ
δ δ
ε ε
ζ ζ
η η
θ θ
ι ι
κ κ
λ λ
μ μ
ν ν
ξ ξ
ο ο
π π
ρ ρ
ς ς
σ σ
σ σ
τ τ
υ υ
φ φ
χ χ
ψ ψ
ω ω
ϑ ϑ
ϒ ϒ
ϖ ϖ
Symbol Encoding
Œ Œ
œ œ
Š Š
š š
Ÿ Ÿ
ƒ ƒ
ˆ ˆ
˜ ˜
– –
— —
‘ ‘
’ ’
‚ ‚
“ “
” ”
„ „
† †
‡ ‡
• •
… …
‰ ‰
′ ′
″ ″
‹ ‹
› ›
‾ ‾
€ €
™ ™
← ←
↑ ↑
→ →
↓ ↓
↔ ↔
↵ ↵
⌈ ⌈
⌉ ⌉
⌊ ⌊
⌋ ⌋
◊ ◊
♠ ♠
♣ ♣
♥ ♥
♦ ♦
• http://www.sitepoint.com/-html-css-beginners-guide/
• http://www.quackit.com/-html/tutorial/
• http://www.skilledup.com/-articles/free-beginner-html-tutorials/
Get your skills up with a great collection of
HTML resources from skilled up! In this article skilled up assembles 20 of the best
HTML tutorials for beginners. Check them out to see who they put in the top 20.
• http://html.net/-tutorials/html/
• http://www.htmldog.com/-guides/html/beginner/
• http://learn.shayhowe.com/-html-css/
• http://www.w3schools.com/-html/default.asp
• http://www.html-5-tutorial.com/
It’s just like they say, “It’s not rocket science!”
At least the folks over at HTML 5 Tutorial think so. To be fair, unless you are really a
complete and total beginner, writing HTML really isn’t rocket science. Add this one to
your list of great resources.
• http://www.codecademy.com/-tracks/web
• https://www.khanacademy.org/-computing/computer-programming/html-css
One of the best free learning resources
available to mankind today is the great Khan Academy. Lucky for us web developers,
they have a fantastic course for HTML and CSS.
• http://teamtreehouse.com/-library/html
• http://www.html5rocks.com/en/
• http://thecodeplayer.com/
• https://developer.mozilla.org/-en-US/Learn/HTML
Chapter 2: PHP
What is PHP?
Now that we’ve just finished a great collection of Tutorials about WordPress, it’s
time to dig into PHP. Why dig into PHP? Well we talked a little bit about all of
the open source software packages that make WordPress possible, but what
we didn’t mention is that the majority and bulk of the program is written in PHP.
With WordPress powering almost a full twenty percent of websites worldwide,
and PHP being the language WordPress is written in, we really ought to have a
good understanding of PHP and how it works! PHP stands for PHP Hypertext
Preprocessor. It actually originally stood for Personal Home Page Tools, which
does seem to be a little easier to digest than the current PHP Hypertext
Preprocessor, but I think we’ll be ok! So without further ado, it’s time for
Random Bits of Awesomeness in PHP!
• PHP is Open Source PHP is open source software which means you are free to
download it, use it, modify it, or otherwise do whatever you want with it. There are no
license fees or restrictions to worry about, and did we mention, it is free.
• PHP is cross platform PHP will run on Windows, Linux, OSX, or any other flavor of
UNIX you can think of. You are not restricted to a proprietary platform with restrictive
lock in.
• PHP is Powerful and Scalable PHP is simple enough to build a super basic website
for your small company website or blog. It will also scale to power multi billion dollar
companies like Yahoo and Facebook, both of which rely on PHP to support their
infrastructure. Many of the very most visited high traffic websites in the entire world
run on PHP.
• Made for the Web PHP was built for the web. The internet and world wide web rely
on many different protocols and aspects of the IP stack to run. PHP has support built
right in for dealing with HTTP hyper text transfer protocol, FTP file transfer protocol,
DNS domain name system, Streams, Sockets, and more. PHP was built for the
internet.
• Object Oriented PHP now has full support for the full range of Object Oriented
techniques available. That means you can use namespaces, classes, objects,
inheritance, control visibility, and use any of the tried and true design principles of
computer science.
• Best Documentation in Town The PHP documentation is arguably the best
language documentation available for any of the modern languages. Every single
function available is clearly documented, with community comments included for
each function. These comments will be invaluable to you as you learn since many
people before you have probably struggled with and solved whatever question you
may have. You’ll find the code snippets to be super helpful.
• Huge Development Community There are over 20 million websites on the internet
that run PHP. That’s a lot of websites, and a lot of software developers that wrote all
of the PHP to run those sites. Any problem you come across has most likely already
been solved, all you have to do is learn how the language works, and learn to
implement the code available to you. Once you have this skill, you can then make
small tweaks and modifications to the code to make things work exactly as you’d like
them to. It’s all very fun!
Powered by PHP
PHP is a fun language to work in for both beginners and professionals alike. In
this PHP Tutorial Series, we’re starting at the ground floor of working with PHP.
It’s really awesome to start from the beginning even for more experienced
developers that need a refresh. Many times, you’ll find advanced problems
often come back around to being very basic missteps. This is what makes the
basics so very important. They are the foundation that you will build your entire
programming knowledge base on. So now that we have taken a look at what
PHP is and the history of this sometimes controversial language, let’s start
getting our hands dirty with PHP. In this episode we’ll take a look at some of the
very basics of the language as well as the request lifecycle and where PHP fits
in to that. Much of these snippets of information are simply bread and butter
basics that we need to know before we go all ninja on ourselves. Let’s get
started!
<body>
<?php
echo 'This text comes from PHP!';
?>
</body>
</html>
echo
Just above, we had already made use of the echo command in PHP. Using this command,
we can do exactly what it says, echo something to the screen. There is another way to do
this as well. In fact, almost anything you can do in programming, you’ll find that there are
many ways to do the same thing. For example, we could rewrite our prior example using
the print command just like this.
index.php
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Welcome to PHP</title>
</head>
<body>
<?php
print 'This text comes from PHP!';
?>
</body>
</html>
Whether we use the first example of echo or the second of print, they will both produce
exactly the same thing in the browser. In fact in both scenarios, if you choose View Source
in your web browser, you can take a look at the HTML that was dynamically generated and
in both cases it looks just like this.
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Welcome to PHP</title>
</head>
<body>
So that is great, and you may be wondering, “Well should I use echo or print?” What is the
difference between echo and print in PHP? There are a couple of differences to be aware
of.
1. echo is faster When PHP executes, the echo command will run faster than the print
statement. To be fair, you wouldn’t in a million years be able to tell the difference
because it is so minute, yet it is a fact that echo is faster.
2. print is a true function In PHP, the echo statement is not a language construct
however the print function is. This makes assigning a return value possible with the
print statement. This is a beginner tutorial however so we’ll just stick to using echo
unless we come across a need for print.
• Apache finds the file This request is interpreted by Apache, and it looks in the
filesystem to find the index.php file.
• The file is interpreted by the PHP engine The web server knows that this file must
be run through the PHP Engine since it has a .php extension.
• The MySQL Database is queried If the file contains any logic to perform a database
interaction, it happens at this step.
• Output is sent to the Browser The data is returned from the database, all PHP is
parsed, and all data is then wrapped up into the final HTML output which gets sent
back to the client. Chrome renders this HTML in the browser and displays a web
page to the user.
The PHP Interpreter Does Not Care About Whitespace
Much like JavaScript, the PHP Engine does not care about whitespace. With JavaScript,
we always see developers minify their code before production. This strips out all
whitespace and non essential characters to produce one massive string of largely
unreadable JavaScript. The web browser doesn’t care however, it is able to run the
JavaScript just the same. With PHP, it is the same idea. There is no need for minification
on the server side however since the file size is not important. The PHP code itself will live
on the server and stay on the server as it executes, unlike JavaScript which must be sent
across the network before the Web Browser can do it’s thing.
This example function will run just fine when called upon.
<?php
function ssba_shorten($urlLong){$hmtlBitly=
file_get_contents('http://api.bit.ly/v3/shorten?login=ninja&apiKey=R_supersecretkey&longUrl='.$urlLon
g);
$arrBitly=json_decode($hmtlBitly,true);$urlShort=$arrBitly['data'];
$urlShort=$urlShort['url'];$hmtlBitly=str_replace('[]','',$hmtlBitly);if($urlShort!=''){return
$urlShort;
}else {return $urlLong;};}
However, you will make things infinitely easier on yourself if you use common formatting to
make the code readable.
<?php
function ssba_shorten($urlLong) {
if ($urlShort != '') {
return $urlShort;
} else {
return $urlLong;
};
}
If the above snippet doesn’t make a ton of sense to you, no need to worry. We’re only
using this to display the value of whitespace to the human coder, that would be you, and
the fact that the machine doesn’t care how the code is formatted – it simply reads in
source following the delimiters and control structures of the language as its means to
process it.
<body>
<?php
echo 'Hi there Jimmy Bob.'; // First we say hi to Jimmy Bob using a one-line c++ style comment
echo 'Hey Jimmy, what is happening?'; # We can note that we are asking Jimmy what's going on
using a shell-style comment
?>
</body>
</html>
In the snippet above we make use of all three styles of comments you can use. You can
try all of them out and see which feels most natural. You can get really creative with these
and outline very specific comments at the beginning of various functions, classes,
methods, and so on. You’ll find that the popular PHP Frameworks have fantastic
comments.
• C++ Style Comments These are one line style comments using the double forward
slash notation //
• Multi Line Comments By using an opening /* and closing */ you can spread the
comment across several lines.
• Shell Style Comments Finally, you have the option of using shell style comments
with the hashtag # character.
Break out your Fender Stratocaster and put some fresh strings on. Plug in to an
epic Marshall Stack and crank it up to 11. Ask the crowd if they’re ready to rock
in your best British accent. We’re about to rock and roll with PHP Variables and
Strings. Our opening riff will tackle some of the naming conventions needed for
crafting your own variables and strings. Next up as you rip up and down the
fretboard, you’ll need to avoid some keywords that are not part of the scales of
your jam. Finally, you will rip into a solo and put your new found skills to use.
Let’s Rock and Roll.
?>
The snippet above contains a bunch of valid variable names. If you were to use these in
your code, they would work just fine. There are some best practices involved however, so
let’s take a look at that idea. First off, the last example of $__coolThing is a bad idea. The
reason is that this variable begins with two underscores. While you can technically do this,
it can be very confusion to others who may need to work with your code. Making matters
worse is the $_thing style of creating a variable. PHP itself uses an underscore for special
use cases. You don’t want to be second guessing yourself when you come across these
instances with one or multiple underscores at the beginning. The overall best practice
variable style to use in PHP is in the form of $my_variable. This may be the case with other
languages, however in PHP you will find that many developers adhere to this style.
PHP Keywords
Another thing to keep in mind are the keywords that PHP already makes use of. These are
all language constructs. Technically, you could still use these as variable names, but why
would you do that? Don’t do it, since you’ll just confuse yourself and others.
__halt_compiler() abstract and array() as
<body>
<?php
$variable = 25;
echo $variable.'<br>';
$variable = 50;
echo $variable.'<br>';
</body>
</html>
On the first line we make use of the assignment operator = to place the value of 25into the
variable aptly named $variable. Line 2 has us using the echo language construct to output
the contents of $variable to the screen. On this same line, note that we use the
concatenation operator . to tack on an html line break tag so that we have some half
decent formatting in place when the script runs. At this point, when the script runs, the
browser will see the value of 25 on the screen.
As the script continues in a top down fashion like all PHP scripts do, we then take the
value of 50 and overwrite the existing value of 25. By simply re assigning a value to an
existing variable, we can overwrite or clobber as some programmers like to say, the value.
When we then echo the same variable to the screen, we can see it is now 50.Excellent work
Jedi.
On line 7 of the script, we create a second variable named $something_else. In the first
two scenarios, we placed number values into the variable. When we do that, we do not
need to enclose the data with single or double quotes. In this last example however, we
are trying to put a string into $something_else and this is why this data is surrounded by
single quotes. Single and double quotes have different meanings in PHP which we will get
to shortly. As the final step in this basic php program, we simply echo out the contents
of $something_else and confirm that yes – You sir, are awesome.
Raw HTML Output
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Variables in PHP</title>
</head>
<body>
</body>
</html>
You might have noticed something there in the form of that backslash character . When we
use strings in PHP and the single quote style, if there are any single quotes within the
string, we’ll need to escape them so the PHP engine knows that this is not the end of our
string, it is an actual character we’d like to work with. This is easy to get tripped up on so
do make a note of it.
<body>
<?php
echo '<div class="alert alert-info"><h1>I Live in an H1 tag</h><br>';
echo '<h3>Isn\'t that pretty neat?</h3><br>';
echo '<span class="label label-success">Why yes, Yes it is good buddy.</span></div>';
?>
</body>
</html>
I Live in an H1 tag
Isn’t that pretty neat?
Why yes, Yes it is good buddy.
So we can see that by including HTML in the string itself, we can greatly change how the
browser displays the data.
<body>
<?php
$verb = 'am chilling';
$state = 'damn awesome';
$person = 'you excellent dude';
</body>
</html>
I am chilling in an H1 tag
Isn’t that pretty damn awesome?
Why yes, Yes it is you excellent dude.
Now this example highlights a few key points. Note that we changed our start and end
quotes in the echo statements to use double quotes. Do you notice anything else different
about those lines from the prior example? Yes that’s right, the double quotes that were
used for class definitions have been changed to single quotes as well as the single quotes
themselves no longer need to be escaped using a backslash. Also notice that in the
output, PHP happily extracted the values we had placed into our variables and output them
to the browser just like we thought they would using interpolation. You’ll also note that the
very first three variables we declared above were assigned strings. So it is quite easy to
assign a string to a variable, and you can make it as long as you like. A test is in order.
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Strings in PHP</title>
</head>
<body>
<?php
$longstring = "This is a string. It's going to be a long one too. That is because we are testing
the practice of assigning strings to variables in PHP. So, let's include some random thoughts and
ideas to make this string have a good length. We could just as easily visit lorem ipsum dot com or
something like that, but who wants to read that crap? Let's instead talk about the Sun, the Moon,
the Ocean, and all other kinds of things while walking on the beach. Yeah.";
echo $longstring;
</body>
</html>
So that was pretty slick. Note that we did make use of a string function there as well. We’ll
get to more details about string functions soon, but for now just now that this particular one
gives us the length of a string. So the full output of that test gives us:
This is a string. It’s going to be a long one too. That is because we are testing the practice of
assigning strings to variables in PHP. So, let’s include some random thoughts and ideas to make this
string have a good length. We could just as easily visit lorem ipsum dot com or something like that,
but who wants to read that crap? Let’s instead talk about the Sun, the Moon, the Ocean, and all other
kinds of things while walking on the beach. Yeah. Pretty neat, that sentence is 457 characters long
Very nice.
Type Strength
PHP is a weakly typed language which means that a variable does not need to be
declared with a type, you simply assign values to the variable regardless of data type.
Their are pros and cons to this approach. For the experienced programmer, it can save
time. For the newcomer, it may lead to some strange results.
Consider the following code:
<?php
$value1 = 1;
$value2 = 2.00;
$value1 holds an integer value, simply because the number 1 was assigned to it. $value2
on the other hand is a float since 2.00 is a floating point value.
Now get ready to have your mind blown.
<?php
$value2 is now a string! By assigning the string value to the variable, you are allowing PHP
to update the variable type based on what has been assigned to the variable. We need to
cover MUCH more ground, but this is a super simple intro to PHP variables and data
types. See you in the next post!
In PHP values that are stored in variables are updated all the time. What
happens when you need a value to maintain consistency though? For that you
can use constants. Similar to how we can assign a value to a variable, we also
assign a value to a constant but the difference is that once you set that constant
value, it cannot be modified. Let’s say you want to be sure the values of certain
variables will not change in your application. For example it would be smart to
determine that your variable named $oneminute has a value of 60 seconds. We
can declare that in a constant like so:
<?php
Notice that we use the define keyword and the constant is in uppercase with no dollar sign
prefix. A different application might be setting the value of a T-shirt you might want to sell
on your website. Maybe you want to be sure it sells for $15 and will not be altered
elsewhere by the program. Let’s create that constant now:
<?php
define(‘TSHIRT’, 15);
Now you can be confident that when you are doing calculations and updates using the
TSHIRT constant, the correct value will be assigned to that constant. You can be confident
that the correct value is present and will not get modified by accident.
The uppercase convention of constants comes from the C programming language. C is the
foundation of all computer science and runs everything from the popular Linux operating
system which often runs apache and MySQL to serve up webpages, to the operating
system of cisco routers and switches, both of which power the vast majority of the internet.
Having this uppercase format makes it easy to identify in the code.
You are free to define as many constants as you may need in your program. PHP has a
large amount of its own pre-defined constants. To check which are in use on your
particular installation, you can run the phpinfo() function in one of your pages to view a
dump of all the configuration parameters including constants.
Be sure to also note that constants can only store values of type integer, float, Boolean, or
string. In other words, constants are used for scalar data type storage.
The following is a list of superglobal variables. Memorizing these will help as we move on
do more in depth features of PHP.
<?php
$GLOBALS //An array of all global variables (Like the global keyword, this allows you to
// access global variables inside a function. for example, as $GLOBALS[‘somevariable’].)
$_SERVER //An array of server environment variables
$_GET //An array of variables passed to the script via the GET method
$_POST //An array of variables passed to the script via the POST method
$_COOKIE //An array of cookie variables
$_FILES //An array of variables related to file uploads
$_ENV //An array of environment variables
$_REQUEST //An array of all user input including the contents of input including
$_GET, $_POST, and $_COOKIE (but not including $_FILES since PHP 4.3.0)
$_SESSION //An array of session variables
When starting out with PHP, or even if you are more advanced, it is important to be aware
of these important aspects of the language. While mundane, having these concepts
mastered will allow you to really focus on the cool things you can do with the language
once we get to the nitty gritty.
So far in this PHP Tutorial Series we have taken a good look at all of the
basics. Some of the topics we looked at include what PHP is is, and what the
history of PHP has been. Moving on from this we covered the beginnings of
variables and strings, two of the most common concepts you’ll run across when
programming in PHP. We then got funky with integers, floating point values,
arrays, and more. Do you see a pattern here? That’s right, we’re hammering
home the basic types so that when we get to more advanced topics, we won’t
even have to think about these things. They will just be second nature. This
leads us to today’s episode of working the Booleans and Constants. They’re
definitely not the most exciting thing in the world, but we’ll try to keep it fun, and
they are a vital component of programming so let’s review them now!
Booleans
Booleans are a really basic thing, they are a just like binary. This is to say you either have
a 1 or a zero, a true or a false value. Booleans can either be true or false, that’s it. If it is
true, this does not means the string true or the number 1, it is simply a truthy value. They
are really useful in programming since we can make use of them to perform various tests.
We’ll be making use of this technique all the time to decide which conditional branch to
take. Booleans can be a little finicky so we should look at a few examples.
<?php
$true = true;
$false = false;
echo $true.'<br>';
echo $false.'<br>';
echo is_bool($true).'<br>';
echo is_bool($false).'<br>';
var_dump($true).'<br>';
var_dump($false).'<br>';
?>
1
1
boolean true
boolean false
There are a few points to consider here. First up, notice that we assigned the boolean
values using lowercase. Some will say you should always use uppercase, however for
the lazy efficient among us, why create the need to hold down the shift or caps lock key if
the end result of true or false is the same? Now the next thing we do is to echo out
these boolean values to the screen. Do not be confused! When using the echo command
in PHP, the language will always try to convert whatever it is you are echoing into
a string. So when you echo out a true boolean, PHP decides that this should be
represented by 1. Ok, makes sense, right? Now, when PHP echoes out a false value, the
same type juggling takes place however instead of outputting a 0 like you think it might, it
simply outputs nothing. Strange Behavior indeed.
To be sure of what you are dealing with, you can make use of the is_bool() function to
check if the variable contains a boolean. You may also want to make use of
the var_dump() function since it outputs both the type and the value for you. Types are a
bit confusing, but the more you work with them, the easier they become to manage.
Constants
It’s nice to be able to make use of variables in programming to be able to do all kinds of
interesting things. There are times when it is needed that we need to store a value in a
variable and keep it that way. You can almost think of a constant that way. It is a technique
to assign a value to a non changing variable, and use it anywhere in the program. Maybe
variable isn’t the best name for this placeholder, and you know what, you’re right – that is
why we call them constants! Constants need to use ALL UPPERCASE and they must be
assigned a value using the define() function. You can not simply use the assignment =
operator like you can with variables. Let’s test it out.
<?php
echo TAX_RATE;
define('TAX_RATE', 7.8);
echo TAX_RATE;
?>
So some strange things happened. First off, we defined the constant tax rate as a string
which is way too high. It echoed out to the browser just fine. Moving through the script
however, we realized that the actual tax rate would be a number value so we try to
redefine it. Guess what? You can’t do that! Once a constant is defined, it is set until the
end of the script life cycle.
Now there is a bit more to constants so let’s examine. Check this out.
<?php
echo __LINE__.'<br>';
echo __FILE__.'<br>';
echo __DIR__.'<br>';
?>
1
C:wampwwwphpconsoleindex.php(61) : eval()'d code
C:wampwwwphpconsole
We didn’t define anything to those constants, yet look at the data they
Now wait just a second!
output when we echo them to the browser! You are witnessing magic my friend, yes
magic. Actually, PHP has a bunch of predefined constants that you can make use in your
scripts right away. As we can see by the example here, __LINE__ provides the line
number which is currently executing. __FILE__ provides the path and filename of the
currently running script. __DIR__ gives us the directory where the currently executing file
lives. These are all very handy, and the fun doesn’t end there. There are also some more
advanced constants to make use of like __FUNCTCION__, __CLASS__, __TRAIT__,
__METHOD__, and __NAMESPACE__ but we’ll get to those in due time as they are a bit
more advanced. For now, as long as we understand the concept of what a constant is and
how we can use it, we’ll be good to go.
The Action Packed Boolean and Constants Summary
Like we mentioned at the outset, booleans and constants might not set the world on fire
with their operation, but they are key concepts to understand when programming.
Booleans are especially key since pretty soon we’ll start looking at conditional statements.
It is by looking at a boolean value that we determine which actions should take place in our
code. Once we’re rocking and rolling with if statements, if else statements, if else if else
statements, switch statements, and so on, booleans will be the very thing that determines
how all of these things work. So while it is true that booleans seem boring with their on or
off true or false nature, we need to have them down cold before moving onward!
It’s time to get with the program friends – we need to Go With The Flow. In this
episode of our PHP Tutorial Series we’ll be taking a closer look at all of
the Flow Control Statements available to us. When we’re working with these
control statements, we’ll be evaluating variables and expressions for
a boolean value and then taking action based on a true or false state. Aren’t
you so glad we just covered booleans now?! In any event we have a lot to
cover, we’ll look at if, elseif, ternary, switch, while, for, foreach, try catch,
and return. Let’s jump into working with the various flow control statements we
have in PHP!
1. if
The workhorse of creating basic conditional logic in your programs is the
trusty ifstatement. We use the if statement to check the boolean value of a variable or
expression contained within a pair of parenthesis. The expression is checked, and if it is
true, the statement will run. No doubt you have seen this before, but let’s look at the
structure of this statement here.
if(expression) {
statement
}
Just as useful is the ability to specify some other statement to run should the expression
being evaluated be false. We can do that with this structure.
if(expression) {
statement
} else {
statement
}
There are opinions abound on the use of the curly braces. If you were to omit them, the
code would still run. There is a fair chance however that the code readability police will
hunt you down and place you under arrest for sloppy coding. The take away, use your
curly braces! If you really have a thing against the curly braces, you could use this
alternative syntax as well.
if(expression) :
statement
else :
statement
endif;
This approach sometimes works if there are large amounts of html in the file you happen to
be working with. You might see this type of syntax in a view file for instance in a model
view controller type application. You can also nest if statements to get the behavior you
want.
if (expression) {
statement
} else {
if (expression) {
statement
} else {
statement
}
}
You can use the above style all you like. If you want to use yet another syntax for the same
effect, you can do that as well. This would be by combining the else and if into one elseif.
This approach is not mandatory, in fact some would say the first approach is a bit more
readable. We’ll show how to use this additional syntax however for completeness.
if (expression) {
statement
} elseif (expression) {
statement
} else {
statement
}
2. ? :
You may be wondering, whats up with the question mark colon in large font? This is the
ever useful ternary operator, and you can think of it as a shorthand expression of a simply
if statement. It’s a handy syntax that isn’t used as much as you’d think it would be. With the
ternary operator, the expression is first evaluated. Then, if that expression is true,
statement1 will run. If the expression is false, statement2 runs. The syntax is shorter, but
contrary to the if statement, it is sometimes not clear exactly what the intended effect was
meant to be when reading the code at a later time. This is the syntax if you would like to
use it.
(expression) ? statement1 : statement2
3. switch
Now we move on to the switch statement. When would we want to use the switch
statement? The switch statement is good when a variable could have one of several
values, and each value would have a different operation associated with it. A good
example might be a variable of $day. Consider there are seven days in the week, and
depending on the day of the week, your program would take a different action for each
scenario. This is how the syntax looks.
switch ($day) {
case 'Monday':
// wipe the cobwebs from your eyes
break;
case 'Tuesday':
// do productive stuff at work
break;
case 'Wednesday':
// cheer for hump day
break;
case 'Thursday':
// grab a beverage on thirsty Thursday
break;
case 'Friday':
// Celebrate the Weekend
break;
case: 'Saturday':
// Keep Celebrating
break;
case: 'Sunday':
// go to Church
default:
// Have a default action if the $day is something other than
// Monday - Sunday
break;
}
There might be a scenario where you want the same action to take place for several
different states of the variable being tested. Maybe you’d like to start celebrating the
weekend on Wednesday, Thursday, and Friday. You can do just that with a fall through
like this.
switch ($day) {
case 'Monday':
// wipe the cobwebs from your eyes
break;
case 'Tuesday':
// do productive stuff at work
break;
case 'Wednesday':
case 'Thursday':
case 'Friday':
// Celebrate the Weekend
break;
case: 'Saturday':
// Keep Celebrating
break;
case: 'Sunday':
// go to Church
default:
// Have a default action if the $day is something other than
// Monday - Sunday
break;
}
4. while
Moving on in our control flow adventures brings us to the while loop. This is the first loop
we have taken a look at. The format follows this format.
while(expression) {
statement
}
That looks an awful lot like an if statement you might be thinking. In fact you are right, the
only difference is that the if is now a while. The way this works is expression is evaluated
and if it is true, the statement runs. The expression then gets evaluated again, and if still
true, the statement runs again. This happens at lightning quick speed, and you can
complete hundreds of statement executions very quickly. The statement will usually have
an ability increment the expression so that the loop does not run forever. If it did not have
this ability, the loop might continue to infinity and the world would end program would
crash. Let’s count by tens to 100 with a while loop.
<?php
$i = 1;
while($i <= 10) {
echo ($i * 10);
echo '<br>';
$i++;
}
?>
10
20
30
40
50
60
70
80
90
100
One other thing you might like to do with your loops is to be
Easy Peasy Lemon Squeesy, People.
able to filter within them and break out of them if needed. You can do this by placing an if
inside the loop and a break inside the loop respectively. Let’s check each number to see if
it is evenly divisible by 3 and output a message indicating so if this is the case. Let’s also
break out of the loop at 80.
<?php
$i = 1;
while($i <= 10) {
$num = ($i * 10);
if(is_int($num / 3)) {
} else {
echo '<br>';
$i++;
if($num == 80){
break;
}
}
?>
10 is not divisible by 3
20 is not divisible by 3
30 is divisible by 3
40 is not divisible by 3
50 is not divisible by 3
60 is divisible by 3
70 is not divisible by 3
80 is not divisible by 3
Smashing! That was awesome stuff.
5. do while
You could rewrite the prior example with a do while loop. The difference with a do while
loop is that since the while condition comes after the actual statement code, the loop will
always run at least a minimum of one time no matter what. With the standard while loop,
there is a chance that the loop will never run at all, since if the expression is false, the loop
won’t run! You’ll have to explore your use case, but it’s safe to say that do while loops are
far less common than while and the other types of loops. This is how to write one if you like
though.
<?php
$i = 1;
do {
$num = ($i * 10);
if(is_int($num / 3)) {
} else {
echo '<br>';
$i++;
if($num == 80){
break;
}
} while($i <= 10);
?>
6. for
The for loop is really the workhorse of looping constructs. It’s a little more clean than the
while loop since it builds the counter right into the expression. No need to have an iterator
in the statement body of the loop with this scenario. We can rewrite our little counting
program with a for loop just like this. Note that the filtering and break mechanisms work
just as well in for loops as they did with while loops. In fact, let’s do the same program but
count by 100’s this time and break the loop at 700. Observe.
<?php
if(is_int($num / 3)) {
} else {
echo '<br>';
if($num == 700){
break;
}
}
?>
7. foreach
We talked a lot about arrays in this PHP Tutorial Series. We even came up with an
Epic PHP Array Functions List to keep as a reference. The time has come now, for us to
iterate over arrays. We will do this with the always useful foreach construct. Sometimes
you’ll just want the values, and other times you might like to get the keys and the values.
There are also a couple of ways to create the loop, so in total you have four options for the
syntax.
foreach ( $array as $value ) {
// do stuff to the value
}
Now let’s put our foreach skills into action. Let’s say we have an array of stocks and we
want to process each one of them in turn. We’ll take an array of ticker symbols that are in
all lowercase. We’ll then place a function inside the loop of our foreach construct, and each
time the loop runs, and new lowercase ticker symbol will be fed into our strtoupper
function. We’ll simply echo this process out to the browser to see it in action.
<?php
$stocks = array('msft', 'goog', 'aapl', 'adbe', 'csco', 'jnpr', 'gpro', 'nflx');
foreach($stocks as $stock) {
echo strtoupper($stock).'<br>';
}
?>
MSFT
GOOG
AAPL
ADBE
CSCO
JNPR
GPRO
NFLX
Now we want to be able to process not only the ticker symbol, but the name of the
company each ticker symbol is associated with. We can do this using the key value pair
syntax of our foreach loop. Check it out.
<?php
$stocks = array(
'msft' => 'Microsoft',
'goog' => 'Google',
'aapl' => 'Apple',
'adbe' => 'Adobe',
'csco' => 'Cisco',
'jnpr' => 'Juniper',
'gpro' => 'Go Pro',
'nflx' => 'Netflix'
);
?>
8. try catch
We all know that computers and the software that run them are 100% fail proof, error free,
and work perfectly at all times. If you believe that last sentence, there is a bridge in
Brooklyn you may consider buying Actually, the try catch construct is available to us
for the very fact that sometimes things can and will go wrong with our software. The try
catch gives us the ability to try something out, and if things don’t go as planned we have a
contingency plan to handle any problems. A perfect example is connecting to a database.
There are several things that could go wrong. To deal with this, just put your code in a try
catch block like so.
<?php
try {
$dbhandle = new PDO('mysql:host=localhost; dbname=vegibit', 'root', '');
if ($dbhandle) {
echo 'We are ready to work with the database!';
}
?>
try {
$dbhandle = new PDO('mysql:host=localhost; dbname=verge', 'root', '');
if ($dbhandle) {
echo 'We are ready to work with the database!';
}
9. return
The return statement is used so much we don’t even think of it many times. It just exists
happily in our code, returning values or control to the calling code going about it’s
business. Usually we’ll see return being used in a function something like this.
<?php
$result = add(5,7);
echo $result;
?>
12
In this code we create a user defined function that returns a value. You necan see when
we call that function by simply writing it’s name and passing in two variables, it assigns or
returns the sum into the variable $result. We are then free to echo out that value to the
screen. Pretty Slick!
$a = 29;
$b = 10;
$result = $a%$b;
The value stored in the $result variable is the remainder when you divide 29 by 10 which
comes out to 9.
The arithmetic operators usually deal with integer and double data types. Due to the
loosely typed nature of the language, applying these operators to strings will cause
unexpected results as PHP starts automagically converting strings to numbers. Pay close
attention to your types in order to avoid creating bugs.
Operating on Strings
The concatenation operator or dot . is that magical glue that allows you to stick strings
together. It’s really fun and I know you will love it. An example is in order:
<?php
$hip = “I ”;
$hop = “am ”;
$hooray = “awesome”;
$result = $hip.$hop.$hooray;
The result is “I am awesome” and yes ladies and gentlemen, you are awesome.
Assignment Operators
To equals or not to equals, that is the question. The handy dandy = sign does not mean
‘equals to’ rather it means ‘is set to’. In a sense you might start to read code from right to
left. When you see
<?php
You could read it in a right to left fashion as in, “cool text is assigned to $myvalue” or left to
right such as “$myvalue is set to cool text”. Whatever makes sense to you!
Values Returned from Assignment
The assignment operator returns a value just like other operators. For example:
$one + $two
Is an expression that results in the value of adding $one and $two.
Another example might be:
$ten = 10;
The value of this whole expression is integer ten.
Using this technique, you can create more involved expressions like:
$foo = 16 + ($bar = 5);
This line sets the value of the $foo variable to 21. First we evaluate the code between the
parentheses setting 5 to $bar, then adding 16 to 5, and finally assigning that entire value to
$foo. As you can see the parentheses work the same way as they do in math, which is to
give precedence to the sub expression between the parentheses.
Combination Operators
Many times in programming you will need to add a value to a variable such as
$x = $x + 10;
Rather than write it out in long form, you can use a combination operator like
$x += 10;
Combined assignment operators exist for all of the arithmetic operators and for the
string concatenation operator.
Pre and Post Increment and Decrement
Pre and post increment (++) and decrement (–) operators share traits with the +=
and -= operators, with some important differences.
Increment operators do two things, which is to increment and assign a value.
<?php
$hi = 7;
echo ++$hi;
On line two, the pre-increment operator is invoked. Interestingly, $hi will get 1 added to it’s
value and then echoed out to the screen as 8. Had the ++ come after the variable, it would
be printed to the screen as 7, and then it’s value would be incremented in memory.
The Reference Operator
The reference operator is represented by an &. What this does is to make reference to the
memory address of a variable rather than make a copy of the value itself. Typically what
happens when you create a variable and then assign that variable to a different one, a
copy gets created.
So setting $x = 7, $y = $x , and $x = 15 would leave you with 7 stored in $y and 15 stored
in $x.
Conversely if you did $x = 7, $y = &$x , and $x = 15 both $x and $y would have value 15.
This happens because $x and $y now point to the same memory address. To change this
relationship, you can use the unset() function.
Comparison Operators
When you need to check the logical value of an expression to true or false, you would use
one of the many comparison operators.
The Equal Operator
It’s easy to get the = and the == operators mixed up. The first refers to assignment, the
second refers to equality. Using == allows you to check if two values are equal to one
another. True is returned if they are equal and false is returned if they are not. Typically
non zero values are true and zero values are false.
Consider:
<?php
$five = 5;
$two = 2;
$five = $two;
$five = $two now evaluates to true! This is because the value 2 gets assigned to $five,
and 2 is a non zero value.
On the other hand:
$five == $two will now evaluate to false. Pay attention to your operators!
Other Comparison Operators
There are many other comparison operators that you will need to be aware of, they are
summarized here:
== Equals $c == $f
===Identical $c === $f
!= Not equal $c != $f
!== Not identical $c !== $f
<> Not equal (comparison operator) $c <> $f
< Less than $c < $f
> Greater than (comparison operator)$c > $f
<= Less than or equal to $c <= $f
>= Greater than or equal to $c >= $f
Logical Operators
Logical operators are important to test conditions. You can use AND, OR, XOR, and NOT
for this purpose. These are often used for checking conditions in control flow structures
and loops.
! NOT !$f Returns true if $f is false and vice versa
&&AND$c && $f Returns true if both $c and $f are true; otherwise false
|| OR $c || $f Returns true if either $c or $f or both are true; otherwise false
and AND$c and $f Same as &&, but with lower precedence
or OR $c or $f Same as ||, but with lower precedence
xor XOR $c x or $f Returns true if either $c or $f is true, and false if they are both true or both false.
Bitwise Operators
By using bitwise operators on integers, you will be able to deal with the exact bits that
represent the integer in question. Bitwise operators are more often used in a low level
fashion such as OS or Network programming in C. They are still available to you in PHP
however and we have them listed here:
& Bitwise AND$c & $f Bits set in $c and $f are set in the result.
| Bitwise OR $c | $f Bits set in $c or $f are set in the result.
~ Bitwise NOT ~$c Bits set in $c are not set in the result and vice versa.
^ Bitwise XOR $c ^ $f Bits set in $c or $f but not in both are set in the result.
<<Left shift $c << $f Shifts $c left $f bits.
>>Right shift $c >> $f Shifts $c right $f bits.
But Wait There’s More! (Operators)
Let’s cover the remaining operators you’ll run into now. The comma operator , is an
important one as it is used to separate arguments in functions and items in an array.
You will also want to be aware of the new and -> operators in order to create a new object
and access methods and properties within said object.
Kind of a control structure but formally listed as an operator is the ternary operator.?: This
handy dandy little bugger is great for having a shorthand form of an if elsestatement.
The form the ternary operator follows is:
condition ? value if true : value if false
Error Suppression Operator
PHP has many useful errors but sometimes you may not want to see them. In this case
you can use the @ operator to suppress them like so:
$error = @(200/0)
Normally this code would through a nasty warning, but we have suppressed it here with @.
Array Operators
Arrays are great fun and very useful. As such, we have numerous operators to use on our
arrays to make them easy to work with.
+ Union $c + $f Returns an array containing everything in $c and $f
== Equality $c == $f Returns true if $c and $f have the same key and pairs
===Identity $c === $fReturns true if $c and $f have the same key and value pairs the same order
!= Inequality $c != $f Returns true if $c and $f are not equal
<> Inequality $c <> $f Returns true if $c and $f are not equal
!== Non Identity$c !== $f Returns true if $c and $f are not identical
Type Operator
In object oriented programming we will cover the instanceof operator. It is used to check if
an object is an instance of a certain class. You would use it like so:
<?php
class awesomeClass{};
$obj = new awesomeClass();
if ($obj instanceof awesomeClass)
echo “obj is an instance of awesomeClass”;
If you made it this far, nice work! You now have the skills to operate successfully on your
data in PHP.
We’ve covered a ton of information about strings in PHP and their associated
string functions, now we’ll take a look at working with numbers in PHP.
Numbers are important. If you think about it, we deal with numbers and math all
day, every day. It helps to be good with numbers for calculating your budget,
picking statistical favorites in your office fantasy league football team, investing
based on numerical data, and oodles of other scenarios. In PHP just like all
other programming languages we’ll typically be dealing with whole numbers
and decimal based numbers. In programming parlance we’d be referring to
integers and floating point numbers respectively. It’s a fairly straightforward
topic and can be fun as well, so let’s jump right in to integers and floating point
numbers in PHP!
Integers in PHP
When we think of integers, we’re talking about whole numbers. 1, 2, 3, 4, 5 and so on.
Integers can also have negative values, so going in the reverse direction is also valid. -1, -
2, -3, and so on are all integers as well. We can do simple math with integers and
everything works just like it does in Algebra. All of the orders of operation and operator
precedence hold true. Parenthesis can be used to assign priority to orders of operation.
Check out this example:
<?php
$variable1 = 9;
$variable2 = 4;
echo ((5 + 4 + $variable1) * $variable2) / 4 -3;
?>
15
As we can see, by following the standard math rules we come up with the answer of 15.
$number = 5;
echo $number = $number + 5;
echo '<br>';
$number = 5;
echo $number += 5;
?>
10
10
These two examples do the same thing, however you can see their syntax is slightly
different. The first example takes the number, then it says assign this number plus 5 and
provide this to us. In the second example we use the plus equals shorthand notation. Note
that it works the same exact way and gives us the same result, but it is easier and faster to
type. This works just the same with multiplication, subtraction, and division. Don’t believe
it?! Check it out:
<?php
$number = 5;
echo $number = $number - 5;
echo '<br>';
$number = 5;
echo $number -= 5;
echo '<br>';
$number = 5;
echo $number = $number * 5;
echo '<br>';
$number = 5;
echo $number *= 5;
echo '<br>';
$number = 5;
echo $number = $number / 5;
echo '<br>';
$number = 5;
echo $number /= 5;
?>
0
0
25
25
1
1
Very Cool!
With the approach we were using above, we were dealing with incrementing and
decrementing by using the number 5. We can do this with any value that the problem to
solve may call for. A very common use case however is simply adding or subtracting one
to a number. This is so because when you work with loops in PHP, adding or subtracting 1
to the iterator happens all the time. Let’s see how to do this.
Post Increment or Decrement
This is the most common way to deal with adding or subtracting a value. Have a look at
this:
<?php
$number = 7;
echo $number++;
echo '<br>';
$number = 7;
echo $number--;
?>
7
7
Hey Wait! Those numbers are the same as when we started! This is because we are doing
post increment and decrement. You see what happens here is PHP echos out the value
first, then increments the variable. If we change up the code just a little, we can see how
this works.
<?php
$number = 7;
$result = $number++;
echo $number;
echo '<br>';
$number = 7;
$result = $number--;
echo $number;
?>
8
6
That’s more like it. In this snippet we make use of a second variable, $result. So the flow
looks like, assign 7 to $number, assign $number to $result then increment $number, echo
out $number. It’s a little tricky but will become second nature to you after a while.
Pre Increment or Decrement
You’ll notice that in making use of the Pre Increment or Decrement, the ++ or -
- goes before the variable, not after. It’s a subtle yet important difference. You can see that
when we echo out the value of the variable, the updated value is produced straight away.
How is this? Well in this case, PHP assigns 7 to $number, it then increments $number by
one, and finally produces the value to the screen. The same flow happens with the
decrement, and this is why the output is 8 and 6.
<?php
$number = 7;
echo ++$number;
echo '<br>';
$number = 7;
echo --$number;
?>
8
6
$num1 = 1;
$num2 = '1';
?>
not equal
2
Verrrrry Interesting… In the first if statement we say if the first variable is not equal to the
second variable, then echo out not equal. This is exactly what happens when the code
runs. Note however that we then echo out variable 1, an integer, plus variable two, a
string, and we get the number 2. This should seem very strange to you if you’re new to
programming. The number 1 plus the letter one can not possibly be 2! What happens with
this is that PHP inspects the second variable and does its best to assume what is meant
by the string 1 in terms of a numerical value since we are trying to complete a math
operation. This is interesting how this type juggling works but you should really make sure
you know what types you are dealing with and explicitly set and convert them as needed
when programming. Don’t rely on PHP to do it for you lest you find yourself in a world of
hurt when you can figure out why things are not working.
?>
7.12
12.12
1.6666666666667
You see we can assign a float to a variable, add a number to a float, or divide a number
which returns a floating point value.
$float = 7.12;
echo round($float, 1);
echo '<br>';
echo ceil($float);
echo '<br>';
echo floor($float);
?>
7.1
8
7
Is that a Float in your Pocket?
Is that a float in your pocket or are you just happy to see me? Many times you’ll need to
check a variable to see if it is a float or an integer. You might also need to simply check to
see if it is a numeric value. There are a few easy ways to do this, let’s see how.
<?php
$float = 7.12;
$integer = 5;
?>
Is 5 an integer? Yep!
Is 7.12 an integer? Nope!
Is 5 a float? Nope!
Is 7.12 a float? Yep!
Is 5 a number? Yep!
Is 7.12 a number? Yep!
The 11 Fun Hacks to Get Your PHP Integers and Floating Point Values Mastered Summary
We covered the beginnings of Integers, Floating Points, and Numeric Values in this action
packed episode of learning PHP fundamentals. So far we’ve take a look at the history of
PHP, how to work with strings, we covered PHP string functions soup to nuts, and now
we’ve got your numbers covered. Stay tuned for even more random bits of awesomeness
about PHP to come in the following episodes.
<body>
<?php
$make = 'Subaru';
$model = 'WRX';
$year = 2016;
Page Two
<html>
<head>
<meta charset="utf-8">
<title>Working With GET and Links in PHP</title>
<link href="css/bootstrap.min.css" rel="stylesheet">
<script src="js/respond.js"></script>
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script src="js/bootstrap.min.js"></script>
</head>
<body>
<pre>
<?php
print_r($_GET);
?>
Array
(
[make] => Subaru
[model] => WRX
[year] => 2016
)
By passing in values to the variables in the query string, we are able to pass data
Cool!
from one page to another via the GET Super Global variable.
2. Encode Your GET Values!
In HTML there are some reserved characters that we must be aware of because if we
include them in a query string without the proper encoding, the URL will break. This table
contains the reserved html characters we need to be aware of.
Reserved Characters in URLs
$ %24
& %26
+ %2b
, %2c
/ %2f
: %3a
; %3b
= %3d
? %3f
@ %40
space %20
“ %22
< %3c
> %3e
# %23
% %25
{ %7b
} %7d
| %7c
%5c
^ %5e
~ %7e
[ %5b
] %5d
` %60
So as you can see, there are quite a few characters that could cause problems for you.
The solution is that instead of using the actual character in the URL, you should use the
the equivalent percent sign hexadecimal digits encoding value in the URL. Ok, we know
there are quite a few characters to be aware of, so go ahead and memorize the table
above, then come back once you’re ready to continue working with URLs in PHP.
You do not have to memorize this table, there are much better things to do with
Just Kidding!
your time! In fact let’s start making good use of that time by talking about the built in
functions in PHP that will do this for you. Don’t memorize all the characters, just remember
the functions to deal with them.
3. urlencode($string)
This here handy function is going to do the dirty work for you. By running the query string
through this function, it will convert any of the reserved characters to their percent / two
digit hexidecimal pair to make your life easier. Spaces become plus signs, while letters,
numbers, underscores, and dashes go through unchanged. We can see this in action and
why this is necessary by breaking our original link. Let’s add a variable to the list of
variables that we’d like to send via the query string. Here is the updated html.
<html>
<head>
<meta charset="utf-8">
<title>Working With GET and Links in PHP Page One</title>
<link href="css/bootstrap.min.css" rel="stylesheet">
<script src="js/respond.js"></script>
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script src="js/bootstrap.min.js"></script>
</head>
<body>
<?php
$make = 'Subaru';
$model = 'WRX';
$year = 2016;
$mods = 'Stage Two Turbo & New Suspension';
echo "<a
href='http://localhost/bootstrapsandbox/pagetwo.php?make=$make&model=$model&year=$year&mods=$mods'>A
Car</a>";
$mods = urlencode($mods);
echo "<a
href='http://localhost/bootstrapsandbox/pagetwo.php?make=$make&model=$model&year=$year&mods=$mods'>A
Car</a>";
?>
</body>
</html>
So what we are doing here is adding a string to our $mods variable. The string is Stage Two
Turbo & New Suspension. Do you see a problem here? That’s right, we’re placing a
reserved character, the ampersand, in the string that we want to pass as a variable in the
URL. This is going to cause some unexpected results! To illustrate the problem, we
created two links, one with the $mods variable left untouched, and the other with
our $mods variable run through the urlencode function. Let’s see the difference.
Link 1
Array
(
[make] => Subaru
[model] => WRX
[year] => 2016
[mods] => Stage Two Turbo
[New_Suspension] =>
)
Link 2
Array
(
[make] => Subaru
[model] => WRX
[year] => 2016
[mods] => Stage Two Turbo & New Suspension
)
Do you see the difference? The first link completely breaks the data! It has turned the
contents of our $mods variable into two entirely different variables! This is sure to rain fire
from the heavens upon your web application. The second link however uses
the $mods variable after it has been massaged by the urlencode function and therefore
does not break our application. The string we wanted, Stage Two Turbo & New Suspension,
is safely nestled inside of the $mods variable with no ill effect. Excellent. Note that this
URL encoding is only needed with GET requests, since they use URLs to send data.
POST requests will not need any of this fancy encoding business.
4. rawurlencode($string)
In addition to the urlencode function, you also have this rawurlencode function available to
you when dealing with URL encoding. This function does all of the same things as
urlencode. Ok, so you may be wondering, why would you use rawurlencode instead of
urlencode. That’s a good question, and the answer will surprise you. (or not). The
rawurlencode converts space characters into %20 which is their percent / hexadecimal
encoding. Recall the urlencode just turns spaces into plus signs. So what’s the big deal
here? Well, there are some best practices to be aware of and here is a summary of when
to use each.
5. rawurlencode vs urlencode
rawurlencode the path
• the path is the part of the url that comes before the ? symbol
• spaces must be encoded as %20
<body>
<?php
$make = 'Subaru Hatchback';
$model = '2016 WRX STI With Stage Two Turbo & New Suspension';
$linkone = rawurlencode($make)."?model=".urlencode($model);
$linktwo = urlencode($make)."?model=".rawurlencode($model);
There are two reasons you should use the first approach.
1. The portion that comes before the ? is where the server is going to be looking on the
filesystem for the file Subaru Hatchback. The server is going to have a better time looking
for a file that uses %20 as a space rather than a literal + sign. In fact the server may not find
this file at all if using a + sign, and your link will break altogether.
2. The portion that comes after the ? is going to be shorter and look much better
using + signs rather than %20. It’s true both methods will work in this case,
but urlencode after the ? is a best practice, so we should do it that way.
One goal that almost every software engineer on earth regardless of discipline
or language they subscribe to has a common goal in mind. This is to keep
things DRY. When we say DRY, we’re not talking about the Mojave Desert type
of DRY, we’re talking about Do Not Repeat Yourself. Hmmm, wait isn’t that
DNRY? Ok, let’s say Don’t Repeat Yourself. You get the idea. Whoops, there
was a repetition right there, see we all need to make an effort to keep it DRY! At
this point in the game, we have all manner of autoloaders, the wonderful
Composer Project, and countless frameworks that strive to help us organize
and maintain some type of sensible architecture that facilitates keeping your
code DRY. In this episode of the PHP Tutorial Adventure, we’ll take a look at
the Brilliant Functions the creators of PHP devised early on to help us with this
goal, and those would be the include, require, include_once, and require_once
functions. Yes, you likely have used these already, but it pays to dig in deeper
to make sure we understand the key points and differences of each approach.
Let’s jump in.
Keep It DRY
One of the great features of PHP is the ability to include code from other files into other
PHP files. Ok, big whoop, you’re probably thinking. You may be right, but this is an
important feature because it is by using this approach that the foundations of code
organization and reuse are born. Let’s keep it right down to basics at this juncture. Forget
frameworks, Composer, and any other advanced methods you might already be using.
We’re going back to procedural Function Based style right about now. Imagine you have a
page on your website and you just created a killer function that does some really awesome
processing of the data you’re working with. Now, two months later, in an entirely different
section of the website and codebase you have a need to process that data the very same
way your original killer function did. Are you going to write that function again? You might,
if you’re just starting, like all of us have done! A better way however would be to include or
require a file which contains the function code you would like access to. Maybe your
function is 30 lines long. In this new file, you can include the file on one line, then call it on
the next so to speak. 2 lines vs 32 lines is a nice ROI. Not only is the lack of typing a
motivating factor, but what if you find a bug in your super awesome function a few months
down the line. Say you had pasted that function code in ten different PHP files within your
website. Guess what Johnny, open up your favorite editor and get ready for some mind
numbing code maintenance because you are now going to have to fix that bug in 10
different places. You know what, Funk That. We’re going to make sure that doesn’t happen
again using the techniques here.
1. include($path)
There is one thing we didn’t mention yet about this fantastic function. This useful function
is not only for including PHP Code, you can place whatever you like in the file to be
included, such as HTML. Pretend your awesome page makes use of some common
elements in the head section, and you have 10 different pages that all use the same head
data. You don’t need to reinvent the wheel each time! Let’s see how this works.
yourawesomepage.php
<html>
<head>
<meta charset="utf-8">
<title>Keep It DRY and Win</title>
<link href="css/bootstrap.min.css" rel="stylesheet">
<script src="js/respond.js"></script>
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script src="js/bootstrap.min.js"></script>
</head>
<body>
</body>
</html>
Now, rather than manually typing out all of that data in the head section into all of your
other pages, lets create a DRY Maker and include that instead.
the_dry_maker.php
<html>
<head>
<meta charset="utf-8">
<title>Keep It DRY and Win</title>
<link href="css/bootstrap.min.css" rel="stylesheet">
<script src="js/respond.js"></script>
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script src="js/bootstrap.min.js"></script>
</head>
Now, when you create your other awesome page, you can do so with style and grace just
like so.
<?php
include('the_dry_maker.php');
?>
<body>
</body>
</html>
Notice that the Dry Maker file doesn’t even have any PHP in it. We are simply using PHP
in the includer file to include non PHP text from the includee file. What this means is that
when the include function runs, PHP essentially shuts off inside of it so you can import non
PHP data. This also brings up the point that if you want to include PHP from the other file,
you’ll need to make sure that you are turning PHP back on in that file. Let’s see this by way
of including an example function.
yourawesomepage.php
<html>
<head>
<meta charset="utf-8">
<title>Keep It DRY and Win</title>
<link href="css/bootstrap.min.css" rel="stylesheet">
<script src="js/respond.js"></script>
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script src="js/bootstrap.min.js"></script>
</head>
<body>
<?php
include('the_dry_maker.php');
echo highfive('Jim', 'Awesome');
?>
</body>
</html>
the_dry_maker.php
<html>
<head>
<meta charset="utf-8">
<title>Keep It DRY and Win</title>
<link href="css/bootstrap.min.css" rel="stylesheet">
<script src="js/respond.js"></script>
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script src="js/bootstrap.min.js"></script>
</head>
<?php
function highfive($name,$state) {
$highfive = "You know what $name? You are $state, give me a high five!";
return $highfive;
}
?>
2. require($path)
When we look at require vs include, it might seem like they are basically the same. In fact,
PHP require and PHP include do all of the same things, except with the following
difference. If require can’t find the file you wish to load, PHP will raise a fatal error and
script will come to a screeching halt. In some cases this might make sense, but in others,
not so much. In the prior example, using include makes sense. It’s great to give high fives,
but probably not mission critical to our application. So if we fail to include The Dry Maker
file, the page will still try to finish executing. Now since we try to call a function on the page
which is referencing a function definition from another file which is now not included we’ll
get an error from that. The key point though is that the include itself will not cause a failure.
On the other hand, lets say your database driven site has all of its database functions in a
file like database_funcs.php. This is an important piece of code, so much so that your site
would not be able to run without it. In this case, require makes sense. Let’s see this in
action, we’ll change the code in yourawesomepage.php to have a typo for the file we’re
looking for. Then we’ll test out the require vs include and see what happens.
Require
<?php
require('tthe_dry_maker.php');
echo highfive('Jim', 'Awesome');
?>
Include
<?php
include('tthe_dry_maker.php');
echo highfive('Jim', 'Awesome');
?>
See the difference?With the require, the script halts right in its tracks as soon as it can’t find
the file, and a fatal error is thrown. Conversely, the include only throws a warning when it
can’t find the file. Later on on in the page however when we try to call the highfive function,
a fatal error is thrown since you can’t call a function that is not defined.
3. include_once($path)
In order to show the difference between include and include_once, let’s modify
yourawesomepage.php to make multiple include calls to the same dry maker file we’ve
been working with to see what happens. Then we’ll try the same test with include_once
and discuss the results.
yourawesomepage.php
<html>
<head>
<meta charset="utf-8">
<title>Keep It DRY and Win</title>
<link href="css/bootstrap.min.css" rel="stylesheet">
<script src="js/respond.js"></script>
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script src="js/bootstrap.min.js"></script>
</head>
<body>
<?php
include('the_dry_maker.php');
echo highfive('Jim', 'Awesome');
?>
<br>
<?php
include('the_dry_maker.php');
echo highfive('Jim', 'Awesome');
?>
</body>
</html>
Page Output
What happens here is that the page runs just fine until it hits the second include statement.
At that point, include pulls in the file and PHP sees that highfive is getting declared again.
This is a big no no and a fatal error is thrown. Now let’s change the code to use
include_once.
yourawesomepage.php
<html>
<head>
<meta charset="utf-8">
<title>Keep It DRY and Win</title>
<link href="css/bootstrap.min.css" rel="stylesheet">
<script src="js/respond.js"></script>
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script src="js/bootstrap.min.js"></script>
</head>
<body>
<?php
include_once('the_dry_maker.php');
echo highfive('Jim', 'Awesome');
?>
<br>
<?php
include_once('the_dry_maker.php');
echo highfive('Jim', 'Awesome');
?>
</body>
</html>
Page Output
You see that when we use the include_once statement, we no longer get
Excellent, no errors!
the fatal error and the page runs perfectly. Why is that? This is because include_once
adds the original path to an array, and if it sees that path attempt to be included again it
will ignore it. So in this code above, when the second include_once statement is hit, PHP
now knows that the path provided was already included so it ignores it. This way, there is
never any attempt to redeclare the highfive function, and everything operates smoothly.
4. require_once($path)
Last up in our list of brilliant functions within PHP is the require_once function. This option
has the properties of the original require function, in addition to the fact that just like
include_once, multiple attempts to require the same file will be ignored. All 4 have specific
applications as you can see, so now you know which is best to use for your applications.
Everything we do with building websites has a dark underside, and it’s called
the HTTP Protocol. Actually, it’s not dark, it’s great as this is what makes all
this internet stuff possible. You see when you visit a website and the server
sends HTML to you over the internet, there is something that comes first,
before any of the HTML even gets to your browser. This is called the HTTP
Header and it contains some valuable information about the web session to
provide to the Browser. This gets sent before anything else. In fact, it is by the
very fact that you tried to visit a website in the first place that this process
began. When you go and type your favorite URL into your browser of choice
and then hit enter, what do you think happens? Your Browser makes use of the
HTTP protocol to send a GET request to the server in the form of an HTTP
Header. So you see all of this is the underpinning of how websites and the
internet works, so we’ll need to get a good grasp of how to use this in PHP.
There are tons of functions and approaches to working directly with HTTP and
HTTP Headers in PHP, so let’s get right into it!
Is HTTP Evil?
You may have noticed the scary implications that the title of this post assigns to PHP.
Actually, HTTP is not all that bad, it may be our friend in fact. It is a bit quirky and tricky at
first however, and this is why we must remain vigilant in our learning. One way to really
learn about the HTTP protocol is to install something like the Live HTTP Headers add on to
Firefox. This gives you the ability to watch all the communication between your web
browser and a remote server in real time. It is quite slick actually. If you have Live HTTP
Headers installed, you can click Tools->Live HTTP Headers and a new window will open
that displays all of the HTTP Headers in a web session. Here is an example of a Request /
Response to Twitter.
request
https://twitter.com/
GET / HTTP/1.1
Host: twitter.com
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:32.0) Gecko/20100101
Firefox/32.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Cookie: guest_id=example cookie data
Connection: keep-alive
response
HTTP/1.1 200 OK
Cache-Control: no-cache, no-store, must-revalidate, pre-check=0, post-check=0
Content-Encoding: gzip
Content-Length: 12361
content-security-policy-report-only: default-src https:; connect-src https:; font-src
https: data:; frame-src https: http://*.twimg.com http://itunes.apple.com about:
javascript:; frame-ancestors https:; img-src https: data:; media-src https:; object-src
https:; script-src ‘unsafe-inline’ ‘unsafe-eval’ about: https:; style-src ‘unsafe-inline’
https:; report-uri;
Content-Type: text/html;charset=utf-8
Date: Thu, 09 Oct 2014 14:36:46 UTC
Expires: Tue, 31 Mar 1981 05:00:00 GMT
Last-Modified: Thu, 09 Oct 2014 14:36:46 GMT
ms: S
Pragma: no-cache
Server: tsa_a
Set-Cookie: _twitter_sess=example session cookie
status: 200 OK
The main thing to note here are the status codes. We can see that Twitter responds back
with a 200 OK, which is a way of saying, “Hey – Everything is Awesome”. There are a
whole range of status codes that exist to help facilitate communication between client and
server. Here is a table of them.
100 Continue
200 OK
201 Created
202 Accepted
204 No Content
302 Found
306 unused
401 Unauthorized
403 Forbidden
409 Conflict
410 Gone
header($string)
Your web server takes care of sending the proper headers to your website visitors
depending on the situation. This is something we normally never even think about as it
happens automatically and transparently in the background. There are occasions when
you the developer may have a need to manually tweak how the headers are presented
from your server and in this case, you can make use of the header()function. Let’s look at
some code that would modify the headers.
<?php
header('Content-Type: application/pdf');
?>
The code above gives examples of how you would send headers for an Adobe PDF
document, a Server Error, a not found page, and a downloadable attachment.
Redirects In PHP
It is actually not all that common to be tinkering with headers in PHP, but there is a use
case that is used all the time and has real value. That use case would be Page
Redirection. Page Redirection is wonderful for instances such as when a user logs into
your site, maybe you’d like them to be redirected right to a key piece of information on a
given page. You can do that with Page Redirection. The popular PHP frameworks all have
this functionality in some easy to use methods, but we can do this right in native PHP as
well. Let’s see how.
302 Redirect
In the HTTP protocol we use a 302 Redirect to make a Page Redirect happen. There are
two parts to this.
The first part says, “Hey you found me” and the second part says, “but you need to go to
this different location now”. Now when we do this in PHP it would look something like this.
Let’s say we’re redirecting someone to the login page.
<?php
header('Location: login.php');
You may be wondering why we didn’t have to manually set the 302 portion of the redirect.
This is because PHP is intelligent enough to do that automatically for you, so all you need
to do is provide the location to redirect to, and bingo. Pay attention to the syntax when
using this approach as it is notoriously finicky. The L in Location must be capitalized,
followed by all lowercase. The double colon must be followed by exactly one whitespace
character. Then you can provide the path to redirect to. What’s interesting is that the
browser actually immediately makes a second GET request once it sees that 302 Redirect.
One other point to keep in mind is that once the redirect happens in PHP, you really don’t
want to send any other data so often you’ll see an exit statement right after the command.
<?php
header('Location: login.php');
exit;
?>
You could even put this in a dedicated redirect function if you like. This is what it might look
like.
<?php
function redirect($new_page) {
header('Location: ' . $new_page);
exit;
}
?>
Now if you want to redirect somebody to Yahoo, you can just do this and send them on
their way.
<?php
function redirect($new_page) {
header('Location: ' . $new_page);
exit;
}
redirect('http://yahoo.com');
?>
In this adventure we’ll be specifically targeting the 2nd approach with POST requests and
HTML Forms in PHP. It is by the $_POST super global variable that we can access data
submitted by the form. The various fields in the HTML Form will have a name attribute
which will then become the key of the associative array in $_POST. You can make use of
form processing via a 2 page process, or a single page form process. There are pros and
cons to each, and for now we’ll take a look at the 2 page approach. What this means is
that your first page will contain the HTML markup for the form. That form will have
an action attribute, and the value of that attribute is the second PHP page that will process
the data. The easiest way to see how this works is to create it in code.
htmlformbuiltwithlove.php
<html>
<head>
<meta charset="utf-8">
<title>HTML Form Built With Love</title>
<link href="css/bootstrap.min.css" rel="stylesheet">
<script src="js/respond.js"></script>
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script src="js/bootstrap.min.js"></script>
</head>
<body>
</body>
</html>
process_form.php
<pre>
<?php
print_r($_POST);
?>
So there we have our two page setup for form processing at its most very basic. If we load
up htmlformbuiltwithlove.php in our browser, we can enter some information into the form.
In the first field we will enter https://ello.co and in the second we’ll enter Social. Then
we’ll hit the Submit Button and see what happens.
Array
(
[website] => https://ello.co
[category] => Social
[submit] => Submit Website
)
Very Cool! You can see how the name attribute became the key in our array, and the data
we typed became the value of that particular key. This data was passed from page one to
page to via the POST method. Let’s look at grabbing the data out of that array and actually
using it. In your actual programs, the sky is the limit in terms of how you can process this
information. Let’s just grab the two values, put them in variables, then use them on the
page somehow. We’ll update the process_form.php file like so and see what we can do.
process_form.php
<html>
<head>
<link href="css/bootstrap.min.css" rel="stylesheet">
<script src="js/respond.js"></script>
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script src="js/bootstrap.min.js"></script>
</head>
<body>
<?php
$website = $_POST['website'];
$category = $_POST['category'];
echo "Hi bud, thanks for submitting <b>$website</b> to the <b>$category</b> category.";
?>
<body>
<?php
echo "Hi bud, thanks for submitting <b>$website</b> to the <b>$category</b> category.";
?>
Loading the this page directly will provide “Hi bud, thanks for submitting http://twitter.com
to the Social category.”, however loading if you submit a blank form from
htmlformbuiltwithlove.php, the processing page will still run but it will have empty values.
<body>
<?php
if(isset($_POST['submit'])) {
echo 'Nice Form Submission!<br>';
} else {
echo 'Stop trying to hack the form fool!';
exit;
}
echo "Hi bud, thanks for submitting <b>$website</b> to the <b>$category</b> category.";
?>
This is great and now provides something more along the lines of what you’d be looking
for. If a user submits valid data to the form, and then hits the submit button, it may look like
this.
Nice Form Submission!
Hi bud, thanks for submitting Google+ to the Social category.
If the user tries to load process_form.php directly however, they are provided this
message.
Stop trying to hack the form fool!
What we are doing is checking for the presence of the submit key in the $_POST array.
The only time that key is present is if a user actually clicked on the submit button in the
form, so this is the way to most easily detect form submission.
?>
<html>
<head>
<meta charset="utf-8">
<title>HTML Form Built With Love</title>
<link href="css/bootstrap.min.css" rel="stylesheet">
<script src="js/respond.js"></script>
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script src="js/bootstrap.min.js"></script>
</head>
<body>
</body>
</html>
Now when this page is loaded initially, or if a blank form is submitted, the user gets the
message, Enter a Website and Category . If the user provides something like
http://facebook.com and Social then clicks submit, they will get a message like Hi bud,
thanks for submitting http://facebook.com to the Social category. Note that we added
just a minimal amount of validation in the if clause as well as running any user input
through htmlspecialchars that we learned about in the htmlentities vs
htmlspecialchars tutorial.
Validation Characteristics
• Presence Did the user actually enter anything into a given field?
• String Length Is the string provided long enough to warrant a valid value?
• Type Check Checking the type of data is quite common.
• Inclusion If there is a drop down list of 10 values, is the value provided one of those
10 possible values?
• Uniqueness Is the data a user is submitting 100% unique? This is common on email
address submissions.
• Format Does the website address contain http:// or does an email contain an @
symbol, etc..
This is the proverbial tip of the iceberg here, as data validation can have hundreds of
characteristics, but remember young Jedi, we’re talking about the basics in this episode.
So let’s see what these types of validation rules might look like in basic PHP.
<?php
// presence
$value = '';
if(!isset($value) or empty($value)) {
echo 'fail';
}
// string length
$value = '';
$min = 2;
$max = 25;
// type
$value = '';
if(!is_string($value)) {
echo 'fail - not a string';
}
// set inclusion
$value = '7';
$set = array('1', '2', '3', '4', '5', '6', '7', '8');
if(!in_array($value, $set)) {
echo 'fail - not in the set';
}
// format
$value = 'tom@jones.com';
if(!preg_match('/@/', $value)) {
echo 'not a valid email';
}
?>
Validation Functions
When not using a full blown framework, the next best thing is to put your validation logic
into reusable functions. Here are some examples we can use to test out on our single
page form validation example.
validation_functions.php
<?php
function has_presence($value) {
return isset($value) and $value !== '';
}
?>
Now we can include this file right into our form page just like this.
<?php
include('validation_functions.php');
$errors = array();
} else {
echo 'Enter a Website and Category';
}
?>
<html>
<head>
<meta charset="utf-8">
<title>HTML Form Built With Love</title>
<link href="css/bootstrap.min.css" rel="stylesheet">
<script src="js/respond.js"></script>
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script src="js/bootstrap.min.js"></script>
</head>
<body>
We now have a fully functioning HTML form which is processed via PHP on the
Fantastic!
same page, uses validation functions to handle validation, and outputs any errors in a nice
list format if something goes wrong.
$name = 'Score';
$value = 575;
$expire = time() + (60*60*24*7);
setcookie($name, $value, $expire);
?>
The first two arguments are pretty easy to deal with. The third can be a little tricky if you’re
not used to it. When setting an expiration time for a cookie, the server needs to send a
UNIX Timestamp as the value. The easiest way to do this is to have PHP generate the
current time in a UNIX Timestamp, then add the amount of time you’d like that cookie to
persist for based on the current time. UNIX Timestamps are precise to the second, so
when we add time to the timestamp, it must also be precise to the second. In other words,
when adding the length of time to the timestamp, it must be done in seconds. So if you
want a cookie to last a week, you need to provide the number seconds in a week, which is
604800. The other way to do this, which is much more common, is to use math to calculate
the amount of time you need. This is how we did it above. It helps to talk it out. We have
60 seconds in a minute, times 60 minutes in an hour, times 24 hours in a day, times seven
days in a week to arrive at the same 604800.
Note: When this PHP code executes, it will instruct the server to send this cookie in the
HTTP Response Header. This is important. Recall that headers are sent before anything
else in the page. In the absence of output buffering, this means that any time you would
like to set a cookie, you need to do so at the very top of the page so that it is included in
the header sent to the client. It is best to use cookies for non sensitive information. Since
they are freely viewable and hackable, cookies make sense for simple user experience
conveniences, but not for critical pieces of the application.
echo '<pre>';
print_r($_COOKIE);
?>
Array
(
[Score] => 575
)
Ah ha!Here we simply do a pretty print of the $_COOKIE super global, but in more common
use cases you would be using the actual key to retrieve the specific value you are looking
for. Let’s see an example of user preferences. We’re going to do a few different things in
this example. First off, we’re going to set the name, value, and expiration right in the
function call itself. We are also going to give these cookies a ridiculously small shelf life,
that being 5 seconds. Lastly we’ll use the actual keys of the $_COOKIE Super Global to
retrieve values only if they’re present.
<?php
echo 'Hi there '.$name.' - You like things that are '.$color.' in color as well as to eat '.$food.'
Food!';
?>
Now we can load the same page just a couple of seconds later and see the result.
Request
http://localhost/bootstrapsandbox/cookies.php
GET /bootstrapsandbox/cookies.php HTTP/1.1
Host: localhost
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Cookie: Name=Chris; Color=Blue; Food=Italian
Connection: keep-alive
Response
HTTP/1.1 200 OK
Date: Tue, 14 Oct 2014 16:48:05 GMT
Server: Apache/2.4.4 (Win32) PHP/5.4.16
X-Powered-By: PHP/5.4.16
Set-Cookie: Name=Chris; expires=Tue, 14-Oct-2014 16:48:10 GMT
Set-Cookie: Color=Blue; expires=Tue, 14-Oct-2014 16:48:10 GMT
Set-Cookie: Food=Italian; expires=Tue, 14-Oct-2014 16:48:10 GMT
Content-Length: 89
Keep-Alive: timeout=5, max=96
Connection: Keep-Alive
Content-Type: text/html
Browser Output
Hi there Chris – You like things that are Blue in color as well as to eat Italian Food!
Great!This really hammers home where cookies fit in during the request response cycle.
Note that on the first request response, we do not see the values of the cookies. This is
because it is not until at least one request is made that the server can then even set a
cookie or cookies in the first place. On the second request response cycle, the request is
carrying the cookies to the server in the header. Therefore PHP is able to hook into those
cookies on the incoming request, extract the values from them, then send the response.
The takeaway: $_COOKIE Super Global holds values from the previous request, it is not
change upon setting the cookie. Pretty slick!.
echo '<pre>';
print_r($_COOKIE);
?>
Array
(
[Name] => Chris
[Color] => Blue
[Food] => Italian
)
Now if we comment out the code that set’s our cookies, we still get the value stored in
those cookies.
<?php
echo '<pre>';
print_r($_COOKIE);
?>
Array
(
[Name] => Chris
[Color] => Blue
[Food] => Italian
)
echo '<pre>';
print_r($_COOKIE);
?>
Array
(
[Color] => Blue
)
Smashing! By passing in a value of null to the second parameter and a time in the past to the
third parameter, we can successfully remove cookies from the user’s browser. Just note
that it is the second request where this actually takes effect.
Sessions In PHP
Sessions are really great tools for managing state and they are related to cookies. The key
difference is that when you think of a session, you should think server side. Cookies are
strictly browser side. A session is a file that is actually stored on the web server. The web
server then sends a cookie to the user that references that session file. You see how that
works? It’s like a two step process where the file on the server and the cookie in the
browser work together to maintain state or share information. There are a few pros and
cons to each approach so lets take a look at them.
Session Pros
• More Storage A cookie can only hold about 4000 characters maximum. You can go
further than this as needed with sessions.
• Smaller Request Sizes By storing the session on the server, there is no need to put
all of this data in the cookie itself for every HTTP Request.
• Hides Data Values You can’t read the value of a session cookie like you can with a
standard cookie in the browser.
• More Secure Since values are hidden, they are less prone to hacking.
Session Cons
• Slower to access They are a tiny bit slower, however you’ll never notice it. We’re
talking milliseconds here.
• Expire Immediately Upon Browser Close Once a user closes their browser, the
session ends.
• Session Files Accumulate Since sessions don’t really expire, they tend to build up
on the web server. They will need to be manually deleted over time.
One thing to be aware of with Sessions in PHP is that the values can be set and retrieved
in the same request response cycle. We saw this is not possible by using standard
cookies. Why is this? This is because with regular cookies, the web server must reach out
to the users browser over HTTP to actually set or get values from cookies. With sessions,
this step can be eliminated. PHP and the web server work directly with a session file
stored on the web server itself, then a cookie gets sent back to the user with a reference to
that file. In many ways, this makes sessions actually easier to use, you don’t have to think
as much. In fact, when storing values in the $_SESSION Super Global, all you have to do is
make up and names you like for the keys, then assign the values you want as needed.
Let’s see an example.
<?php
session_start();
echo '<pre>';
$_SESSION['boo'] = 'yeah';
$_SESSION['hip'] = 'hop';
$_SESSION['ying'] = 'yang';
print_r($_SESSION);
?>
Array
(
[boo] => yeah
[hip] => hop
[ying] => yang
)
This PHP Tutorial Series has gone soup to nuts covering all of the fundamental
aspects of using PHP to build dynamic websites. Based on all of the concepts
covered so far, you should be able to build links to pages, pass data
via $_GET in those links, create forms, collect user data via $_POST in those
forms, as well as use cookies and sessions to establish state and customized
user experiences. One thing we haven’t talked about yet is working
with MySQL in PHP. A fantastic place to start if you are new to MySQL is right
at our dedicated 10 Part MySQL Tutorial Series. That will give you a fantastic
foundation on which to build upon for working with MySQL in PHP. In this part
of our PHP Tutorial Series, we’ll take a look at MySQL in terms of using PHP to
read and write data, store data, organize data, as well as set up relationships of
data.
Database APIs in PHP
First off let’s talk a little bit about database apis in PHP. In plain vanilla terms we have
three options that are built into the PHP language. The first is mysql, which is the original
MySQL api for PHP. The next option is mysqli, which is the MySQL Improved version of
the api. Lastly, PHP has PDO, or PHP Data Objects. In reality, the old mysql can be largely
ignored unless you are tasked with maintaining a legacy code base. In the current web
development world you’ll be using either mysqli or PDO. Let’s look at a chart to view the
differences between the three.
mysql mysqli PDO
Deprecated v5.5
This is a great overview of your options of using PHP to interact with your database. In this
episode we’re going to look at mysqli and focus on the procedural approach. This is not to
say that you can not use mysqli in an object oriented approach, you very much can. In fact
let’s compare the two approaches side by side.
mysqli Procedural Syntax mysqli OOP syntax
mysqli_connect_error $mysqli->connect_error
mysqli_real_escape_string $mysqli->real_escape_string
mysqli_query $mysqli->query
mysqli_fetch_assoc $mysqli->fetch_assoc
mysqli_close $mysqli->close
The 5 Steps
Now that we have a bit of a high level overview, let’s look at the five steps of database
connectivity in PHP. These five steps are really the bread and butter of connecting to your
database and you will use this approach no matter what type of interface you choose, so it
makes sense to understand the concept of each step. This will make you a better
programmer and give you a better ability to troubleshoot issues when things don’t quite go
the way you had planned.
• 1. Create The Database Connection. You can think of this step almost like picking
up a telephone and making a call to someone. Once that call is established, you
have a valid connection. The same idea applies when dealing with databases.
• 2. Perform A Query. With your knowledge of MySQL, you can now begin running
queries using SELECT INSERT UPDATE and DELETE in addition to the other
commands available.
• 3. Make Use of Data Retrieved. In the case of getting back any data from a query,
you can make use of that data. It may involve emailing that data to someone or just
outputting it to the screen.
• 4. Release Memory. Once you’re done with the prior operation, it’s time to release
any memory that was used to hold the data from step 3.
• 5. Close The Connection. Once the conversation between PHP and the Database
is complete, you need to close the connection. This is much like hanging up the
telephone once your conversation is complete.
// open a connection
$dhost = 'localhost';
$duser = 'root';
$dpw = '';
$dname = 'wordpress';
$connection = mysqli_connect($dhost, $duser, $dpw, $dname);
?>
This is what you get when everything goes right, an object of type mysqli.
object(mysqli)[1]
public 'affected_rows' => null
public 'client_info' => null
public 'client_version' => null
public 'connect_errno' => null
public 'connect_error' => null
public 'errno' => null
public 'error' => null
public 'error_list' => null
public 'field_count' => null
public 'host_info' => null
public 'info' => null
public 'insert_id' => null
public 'server_info' => null
public 'server_version' => null
public 'stat' => null
public 'sqlstate' => null
public 'protocol_version' => null
public 'thread_id' => null
public 'warning_count' => null
Wrong User
Something went wrong with the database
Wrong Password
Something went wrong with the database
It is human nature to jump right into things and say, “Hey! What could possibly go wrong?!”
We know that things can and do go wrong, so it’s best to include the code that can output
some useful information to you so that you understand the problem.
// Step 1
// open a connection
$dhost = 'localhost';
$duser = 'root';
$dpw = '';
$dname = 'wordpress';
$connection = mysqli_connect($dhost, $duser, $dpw, $dname);
// Step 2
// test the connection
if(mysqli_connect_errno()){
die('Something went wrong with the database<br><br> '
. mysqli_connect_error() . ':'
. mysqli_connect_errno());
}
// Step 3
// define the query
$query1 = "select * from wp_posts";
// Step 4
// run the query to get a resource placed in $result
$result = mysqli_query($connection, $query2);
// Step 5
// test to see if the query was successful
if(!$result) {
die('The query was not successful.');
} else {
// Step 6
// the query was successful so let's get the data if there is some
// as long as there is another row in the $result, assign it to $row
while($row = mysqli_fetch_row($result)) {
// output each row
var_dump($row);
}
// Step 7
// Release the returned data
mysqli_free_result($result);
}
// Step 8
// close the connection
if(mysqli_close($connection) == true) {
echo 'Database connection closed.';
}
?>
Note that we use two styles to build up the query. If you like you can simply build the query
in one big long string as we do in $query1, or, you can incrementally build the query string
using the .= operator like we did with $query2. This sometimes helps to be able to ‘think
out’ your query so to speak.
Now we can see why PHP frameworks are so popular. All of this leg work is done pretty
much automagically for you. When using raw PHP, you’re going to need to write all of this
code to talk to and work with the database. In truth however, it is super important that you
can actually do this work using raw PHP for if you can’t, you will be dead in the water if
something goes wrong on you when you’re using a framework. This is because you won’t
have even the slightest clue as to how the framework might be handling the native code for
you. So let’s review the basic idea of the steps needed to make a query.
Run A Query
$result = mysqli_query( $connection , 'select * from wp_posts' );
Conclusion
There you have it friends, everything you need to use native PHP to work with a MySQL
database. Yes, it almost seems like a lost art in these days of Hyper Capable Modern PHP
Frameworks, but it pays to come back to basics to make sure the foundation is solid.
In the prior episode of working with MySQL and PHP, we took a good look at
the entire process of getting data to work with. This involved setting up a
database connection, testing the database connection, defining a query,
running said query, processing any results we got back, releasing memory, and
closing the database connection. Bing, Bang, Boom, we’re talking to the
database successfully. In this PHP and MySQL Tutorial we’ll take a closer look
at the processing portion of this cycle. So far we have only looked
at mysqli_fetch_row, but now we’ll take a look
at mysqli_fetch_assoc, mysqli_fetch_array, and mysqli_fetch_object as
well. There are some similarities and differences between the various
approaches so we’ll examine those as well. Let’s jump in!
Processing Returned Query Data
There are four ways to process the data we get back from a query. The first approach is
simply using the mysqli_fetch_row option. This retrieves a row of data from the database
and assigns it to a standard array. There is nothing fancy about this array, and the keys of
this array are simply 0 based integers. For example this query will return three rows of data
from the wp_posts table of a WordPress database.
1. mysqli_fetch_row
<?php
// Step 1
// open a connection
$dhost = 'localhost';
$duser = 'root';
$dpw = '';
$dname = 'wordpress';
$connection = mysqli_connect($dhost, $duser, $dpw, $dname);
// Step 2
// test the connection
if(mysqli_connect_errno()){
die('Something went wrong with the database<br><br> '
. mysqli_connect_error() . ':'
. mysqli_connect_errno());
}
// Step 3
// define the query
$query1 = "select * from wp_posts";
// Step 4
// run the query to get a resource placed in $result
$result = mysqli_query($connection, $query2);
// Step 5
// test to see if the query was successful
if(!$result) {
die('The query was not successful.');
} else {
// Step 6
// the query was successful so let's get the data if there is some
// as long as there is another row in the $result, assign it to $row
while($row = mysqli_fetch_row($result)) {
// output each row
var_dump($row);
}
// Step 7
// Release the returned data
mysqli_free_result($result);
}
// Step 8
// close the connection
if(mysqli_close($connection) == true) {
echo 'Database connection closed.';
}
?>
Here is the output of your three posts. Notice that each key in the array is just an integer
which is not exactly the most helpful way of identifying what you are dealing with. A pro is
that this approach is the fastest of all options.
array (size=23)
0 => string '3518' (length=4)
1 => string '1' (length=1)
2 => string '2014-01-07 21:51:27' (length=19)
3 => string '2014-01-07 21:51:27' (length=19)
4 => string '' (length=9243)
5 => string 'Install Laravel on Windows' (length=26)
6 => string '' (length=0)
7 => string 'publish' (length=7)
8 => string 'open' (length=4)
9 => string 'open' (length=4)
10 => string '' (length=0)
11 => string 'install-laravel-on-windows' (length=26)
12 => string '' (length=0)
13 => string '' (length=0)
14 => string '2014-01-07 21:51:27' (length=19)
15 => string '2014-01-07 21:51:27' (length=19)
16 => string '' (length=0)
17 => string '0' (length=1)
18 => string 'http://vegibit.com/?p=3518' (length=26)
19 => string '0' (length=1)
20 => string 'post' (length=4)
21 => string '' (length=0)
22 => string '9' (length=1)
array (size=23)
0 => string '3582' (length=4)
1 => string '1' (length=1)
2 => string '2014-01-20 20:33:01' (length=19)
3 => string '2014-01-20 20:33:01' (length=19)
4 => string '' (length=7009)
5 => string 'Crud In Laravel 4' (length=17)
6 => string '' (length=0)
7 => string 'publish' (length=7)
8 => string 'open' (length=4)
9 => string 'open' (length=4)
10 => string '' (length=0)
11 => string 'crud-in-laravel-4' (length=17)
12 => string '' (length=0)
13 => string '' (length=0)
14 => string '2014-01-20 20:33:01' (length=19)
15 => string '2014-01-20 20:33:01' (length=19)
16 => string '' (length=0)
17 => string '0' (length=1)
18 => string 'http://vegibit.com/?p=3582' (length=26)
19 => string '0' (length=1)
20 => string 'post' (length=4)
21 => string '' (length=0)
22 => string '5' (length=1)
array (size=23)
0 => string '3658' (length=4)
1 => string '1' (length=1)
2 => string '2014-01-25 03:11:55' (length=19)
3 => string '2014-01-25 03:11:55' (length=19)
4 => string '' (length=29)
6 => string '' (length=0)
7 => string 'publish' (length=7)
8 => string 'open' (length=4)
9 => string 'open' (length=4)
10 => string '' (length=0)
11 => string 'laravel-eloquent-orm-tutorial-2' (length=31)
12 => string '' (length=0)
13 => string '' (length=0)
14 => string '2014-01-25 03:11:55' (length=19)
15 => string '2014-01-25 03:11:55' (length=19)
16 => string '' (length=0)
17 => string '0' (length=1)
18 => string 'http://vegibit.com/?p=3658' (length=26)
19 => string '0' (length=1)
20 => string 'post' (length=4)
21 => string '' (length=0)
22 => string '6' (length=1)
2. mysqli_fetch_assoc
An easier way to work with the data is to be able to have the database field names be the
key names of the array. To do this, you can simply use mysqli_fetch_assocfunction.
Simply update the while loop to use this function like so.
<?php
while($row = mysqli_fetch_assoc($result)) {
// output each row
var_dump($row);
}
Now here are the three posts and notice that the keys of the array are nice descriptive
names. These are the field names from the table you pulled the data from. So the
difference between mysqli_fetch_row and mysqli_fetch_assoc is
that mysqli_fetch_row places results into a standard
array and mysqli_fetch_assoc places results into an associative array.
array (size=23)
'ID' => string '3518' (length=4)
'post_author' => string '1' (length=1)
'post_date' => string '2014-01-07 21:51:27' (length=19)
'post_date_gmt' => string '2014-01-07 21:51:27' (length=19)
'post_content' => string ''(length=9243)
'post_title' => string 'Install Laravel on Windows' (length=26)
'post_excerpt' => string '' (length=0)
'post_status' => string 'publish' (length=7)
'comment_status' => string 'open' (length=4)
'ping_status' => string 'open' (length=4)
'post_password' => string '' (length=0)
'post_name' => string 'install-laravel-on-windows' (length=26)
'to_ping' => string '' (length=0)
'pinged' => string '' (length=0)
'post_modified' => string '2014-01-07 21:51:27' (length=19)
'post_modified_gmt' => string '2014-01-07 21:51:27' (length=19)
'post_content_filtered' => string '' (length=0)
'post_parent' => string '0' (length=1)
'guid' => string 'http://vegibit.com/?p=3518' (length=26)
'menu_order' => string '0' (length=1)
'post_type' => string 'post' (length=4)
'post_mime_type' => string '' (length=0)
'comment_count' => string '9' (length=1)
array (size=23)
'ID' => string '3582' (length=4)
'post_author' => string '1' (length=1)
'post_date' => string '2014-01-20 20:33:01' (length=19)
'post_date_gmt' => string '2014-01-20 20:33:01' (length=19)
'post_content' => string '' (length=7009)
'post_title' => string 'Crud In Laravel 4' (length=17)
'post_excerpt' => string '' (length=0)
'post_status' => string 'publish' (length=7)
'comment_status' => string 'open' (length=4)
'ping_status' => string 'open' (length=4)
'post_password' => string '' (length=0)
'post_name' => string 'crud-in-laravel-4' (length=17)
'to_ping' => string '' (length=0)
'pinged' => string '' (length=0)
'post_modified' => string '2014-01-20 20:33:01' (length=19)
'post_modified_gmt' => string '2014-01-20 20:33:01' (length=19)
'post_content_filtered' => string '' (length=0)
'post_parent' => string '0' (length=1)
'guid' => string 'http://vegibit.com/?p=3582' (length=26)
'menu_order' => string '0' (length=1)
'post_type' => string 'post' (length=4)
'post_mime_type' => string '' (length=0)
'comment_count' => string '5' (length=1)
array (size=23)
'ID' => string '3658' (length=4)
'post_author' => string '1' (length=1)
'post_date' => string '2014-01-25 03:11:55' (length=19)
'post_date_gmt' => string '2014-01-25 03:11:55' (length=19)
'post_content' => string ''(length=16826)
'post_title' => string 'Laravel Eloquent ORM Tutorial' (length=29)
'post_excerpt' => string '' (length=0)
'post_status' => string 'publish' (length=7)
'comment_status' => string 'open' (length=4)
'ping_status' => string 'open' (length=4)
'post_password' => string '' (length=0)
'post_name' => string 'laravel-eloquent-orm-tutorial-2' (length=31)
'to_ping' => string '' (length=0)
'pinged' => string '' (length=0)
'post_modified' => string '2014-01-25 03:11:55' (length=19)
'post_modified_gmt' => string '2014-01-25 03:11:55' (length=19)
'post_content_filtered' => string '' (length=0)
'post_parent' => string '0' (length=1)
'guid' => string 'http://vegibit.com/?p=3658' (length=26)
'menu_order' => string '0' (length=1)
'post_type' => string 'post' (length=4)
'post_mime_type' => string '' (length=0)
'comment_count' => string '6' (length=1)
3. mysqli_fetch_array
The third option for you if you’re unable to make up your mind which of the first two are
better, is to use the mysqli_fetch_array. Why you say? Because this function returns both
index based and associative style in one big array. We’ll update the while loop one more
time, then output the results. Note that this approach is probably not ideal since it is more
computational and memory intensive for no real gain.
<?php
while($row = mysqli_fetch_array($result)) {
// output each row
var_dump($row);
}
Once again, here are the three posts with the output processed by mysqli_fetch_array
array (size=46)
0 => string '3518' (length=4)
'ID' => string '3518' (length=4)
1 => string '1' (length=1)
'post_author' => string '1' (length=1)
2 => string '2014-01-07 21:51:27' (length=19)
'post_date' => string '2014-01-07 21:51:27' (length=19)
3 => string '2014-01-07 21:51:27' (length=19)
'post_date_gmt' => string '2014-01-07 21:51:27' (length=19)
4 => string ''(length=9243)
'post_content' => string '' (length=9243)
5 => string 'Install Laravel on Windows' (length=26)
'post_title' => string 'Install Laravel on Windows' (length=26)
6 => string '' (length=0)
'post_excerpt' => string '' (length=0)
7 => string 'publish' (length=7)
'post_status' => string 'publish' (length=7)
8 => string 'open' (length=4)
'comment_status' => string 'open' (length=4)
9 => string 'open' (length=4)
'ping_status' => string 'open' (length=4)
10 => string '' (length=0)
'post_password' => string '' (length=0)
11 => string 'install-laravel-on-windows' (length=26)
'post_name' => string 'install-laravel-on-windows' (length=26)
12 => string '' (length=0)
'to_ping' => string '' (length=0)
13 => string '' (length=0)
'pinged' => string '' (length=0)
14 => string '2014-01-07 21:51:27' (length=19)
'post_modified' => string '2014-01-07 21:51:27' (length=19)
15 => string '2014-01-07 21:51:27' (length=19)
'post_modified_gmt' => string '2014-01-07 21:51:27' (length=19)
16 => string '' (length=0)
'post_content_filtered' => string '' (length=0)
17 => string '0' (length=1)
'post_parent' => string '0' (length=1)
18 => string 'http://vegibit.com/?p=3518' (length=26)
'guid' => string 'http://vegibit.com/?p=3518' (length=26)
19 => string '0' (length=1)
'menu_order' => string '0' (length=1)
20 => string 'post' (length=4)
'post_type' => string 'post' (length=4)
21 => string '' (length=0)
'post_mime_type' => string '' (length=0)
22 => string '9' (length=1)
'comment_count' => string '9' (length=1)
array (size=46)
0 => string '3582' (length=4)
'ID' => string '3582' (length=4)
1 => string '1' (length=1)
'post_author' => string '1' (length=1)
2 => string '2014-01-20 20:33:01' (length=19)
'post_date' => string '2014-01-20 20:33:01' (length=19)
3 => string '2014-01-20 20:33:01' (length=19)
'post_date_gmt' => string '2014-01-20 20:33:01' (length=19)
4 => string ''(length=7009)
'post_content' => string ''(length=7009)
5 => string 'Crud In Laravel 4' (length=17)
'post_title' => string 'Crud In Laravel 4' (length=17)
6 => string '' (length=0)
'post_excerpt' => string '' (length=0)
7 => string 'publish' (length=7)
'post_status' => string 'publish' (length=7)
8 => string 'open' (length=4)
'comment_status' => string 'open' (length=4)
9 => string 'open' (length=4)
'ping_status' => string 'open' (length=4)
10 => string '' (length=0)
'post_password' => string '' (length=0)
11 => string 'crud-in-laravel-4' (length=17)
'post_name' => string 'crud-in-laravel-4' (length=17)
12 => string '' (length=0)
'to_ping' => string '' (length=0)
13 => string '' (length=0)
'pinged' => string '' (length=0)
14 => string '2014-01-20 20:33:01' (length=19)
'post_modified' => string '2014-01-20 20:33:01' (length=19)
15 => string '2014-01-20 20:33:01' (length=19)
'post_modified_gmt' => string '2014-01-20 20:33:01' (length=19)
16 => string '' (length=0)
'post_content_filtered' => string '' (length=0)
17 => string '0' (length=1)
'post_parent' => string '0' (length=1)
18 => string 'http://vegibit.com/?p=3582' (length=26)
'guid' => string 'http://vegibit.com/?p=3582' (length=26)
19 => string '0' (length=1)
'menu_order' => string '0' (length=1)
20 => string 'post' (length=4)
'post_type' => string 'post' (length=4)
21 => string '' (length=0)
'post_mime_type' => string '' (length=0)
22 => string '5' (length=1)
'comment_count' => string '5' (length=1)
array (size=46)
0 => string '3658' (length=4)
'ID' => string '3658' (length=4)
1 => string '1' (length=1)
'post_author' => string '1' (length=1)
2 => string '2014-01-25 03:11:55' (length=19)
'post_date' => string '2014-01-25 03:11:55' (length=19)
3 => string '2014-01-25 03:11:55' (length=19)
'post_date_gmt' => string '2014-01-25 03:11:55' (length=19)
4 => string ''(length=16826)
'post_content' => string ''(length=16826)
5 => string 'Laravel Eloquent ORM Tutorial' (length=29)
'post_title' => string 'Laravel Eloquent ORM Tutorial' (length=29)
6 => string '' (length=0)
'post_excerpt' => string '' (length=0)
7 => string 'publish' (length=7)
'post_status' => string 'publish' (length=7)
8 => string 'open' (length=4)
'comment_status' => string 'open' (length=4)
9 => string 'open' (length=4)
'ping_status' => string 'open' (length=4)
10 => string '' (length=0)
'post_password' => string '' (length=0)
11 => string 'laravel-eloquent-orm-tutorial-2' (length=31)
'post_name' => string 'laravel-eloquent-orm-tutorial-2' (length=31)
12 => string '' (length=0)
'to_ping' => string '' (length=0)
13 => string '' (length=0)
'pinged' => string '' (length=0)
14 => string '2014-01-25 03:11:55' (length=19)
'post_modified' => string '2014-01-25 03:11:55' (length=19)
15 => string '2014-01-25 03:11:55' (length=19)
'post_modified_gmt' => string '2014-01-25 03:11:55' (length=19)
16 => string '' (length=0)
'post_content_filtered' => string '' (length=0)
17 => string '0' (length=1)
'post_parent' => string '0' (length=1)
18 => string 'http://vegibit.com/?p=3658' (length=26)
'guid' => string 'http://vegibit.com/?p=3658' (length=26)
19 => string '0' (length=1)
'menu_order' => string '0' (length=1)
20 => string 'post' (length=4)
'post_type' => string 'post' (length=4)
21 => string '' (length=0)
'post_mime_type' => string '' (length=0)
22 => string '6' (length=1)
'comment_count' => string '6' (length=1)
4. mysqli_fetch_object
Last up is the ability to fetch rows as objects using the mysqli_fetch_object function. Note
the updated syntax and associated updated output of our query for three posts in a
WordPress database.
<?php
while($row = mysqli_fetch_object($result)) {
// output each row
var_dump($row);
}
object(stdClass)[3]
public 'ID' => string '3518' (length=4)
public 'post_author' => string '1' (length=1)
public 'post_date' => string '2014-01-07 21:51:27' (length=19)
public 'post_date_gmt' => string '2014-01-07 21:51:27' (length=19)
public 'post_content' => string ''(length=9243)
public 'post_title' => string 'Install Laravel on Windows' (length=26)
public 'post_excerpt' => string '' (length=0)
public 'post_status' => string 'publish' (length=7)
public 'comment_status' => string 'open' (length=4)
public 'ping_status' => string 'open' (length=4)
public 'post_password' => string '' (length=0)
public 'post_name' => string 'install-laravel-on-windows' (length=26)
public 'to_ping' => string '' (length=0)
public 'pinged' => string '' (length=0)
public 'post_modified' => string '2014-01-07 21:51:27' (length=19)
public 'post_modified_gmt' => string '2014-01-07 21:51:27' (length=19)
public 'post_content_filtered' => string '' (length=0)
public 'post_parent' => string '0' (length=1)
public 'guid' => string 'http://vegibit.com/?p=3518' (length=26)
public 'menu_order' => string '0' (length=1)
public 'post_type' => string 'post' (length=4)
public 'post_mime_type' => string '' (length=0)
public 'comment_count' => string '9' (length=1)
object(stdClass)[4]
public 'ID' => string '3582' (length=4)
public 'post_author' => string '1' (length=1)
public 'post_date' => string '2014-01-20 20:33:01' (length=19)
public 'post_date_gmt' => string '2014-01-20 20:33:01' (length=19)
public 'post_content' => string ''(length=7009)
public 'post_title' => string 'Crud In Laravel 4' (length=17)
public 'post_excerpt' => string '' (length=0)
public 'post_status' => string 'publish' (length=7)
public 'comment_status' => string 'open' (length=4)
public 'ping_status' => string 'open' (length=4)
public 'post_password' => string '' (length=0)
public 'post_name' => string 'crud-in-laravel-4' (length=17)
public 'to_ping' => string '' (length=0)
public 'pinged' => string '' (length=0)
public 'post_modified' => string '2014-01-20 20:33:01' (length=19)
public 'post_modified_gmt' => string '2014-01-20 20:33:01' (length=19)
public 'post_content_filtered' => string '' (length=0)
public 'post_parent' => string '0' (length=1)
public 'guid' => string 'http://vegibit.com/?p=3582' (length=26)
public 'menu_order' => string '0' (length=1)
public 'post_type' => string 'post' (length=4)
public 'post_mime_type' => string '' (length=0)
public 'comment_count' => string '5' (length=1)
object(stdClass)[3]
public 'ID' => string '3658' (length=4)
public 'post_author' => string '1' (length=1)
public 'post_date' => string '2014-01-25 03:11:55' (length=19)
public 'post_date_gmt' => string '2014-01-25 03:11:55' (length=19)
public 'post_content' => string ''(length=16826)
public 'post_title' => string 'Laravel Eloquent ORM Tutorial' (length=29)
public 'post_excerpt' => string '' (length=0)
public 'post_status' => string 'publish' (length=7)
public 'comment_status' => string 'open' (length=4)
public 'ping_status' => string 'open' (length=4)
public 'post_password' => string '' (length=0)
public 'post_name' => string 'laravel-eloquent-orm-tutorial-2' (length=31)
public 'to_ping' => string '' (length=0)
public 'pinged' => string '' (length=0)
public 'post_modified' => string '2014-01-25 03:11:55' (length=19)
public 'post_modified_gmt' => string '2014-01-25 03:11:55' (length=19)
public 'post_content_filtered' => string '' (length=0)
public 'post_parent' => string '0' (length=1)
public 'guid' => string 'http://vegibit.com/?p=3658' (length=26)
public 'menu_order' => string '0' (length=1)
public 'post_type' => string 'post' (length=4)
public 'post_mime_type' => string '' (length=0)
public 'comment_count' => string '6' (length=1)
// Step 1
// open a connection
$dhost = 'localhost';
$duser = 'root';
$dpw = '';
$dname = 'wordpress';
$connection = mysqli_connect($dhost, $duser, $dpw, $dname);
// Step 2
// test the connection
if(mysqli_connect_errno()){
die('Something went wrong with the database<br><br> '
. mysqli_connect_error() . ':'
. mysqli_connect_errno());
}
// Step 3
// define the query
$query1 = "select * from wp_posts";
// build up the query style
$query2 = "SELECT * ";
$query2 .= "FROM `wp_posts` ";
$query2 .= "WHERE `post_title` LIKE '%laravel%' ";
$query2 .= "LIMIT 0 , 3 ";
// Step 4
// run the query to get a resource placed in $result
$result = mysqli_query($connection, $query2);
// Step 5
// test to see if the query was successful
if(!$result) {
die('The query was not successful.');
} else {
// Step 6
// the query was successful so let's get the data if there is some
// as long as there is another row in the $result, assign it to $row
while($post = mysqli_fetch_assoc($result)) {
// output each row
echo 'The post ID is '.$post['ID'].'<br>';
echo 'The post title is '.$post['post_title'].'<br><br>';
}
// Step 7
// Release the returned data
mysqli_free_result($result);
}
// Step 8
// close the connection
if(mysqli_close($connection) == true) {
echo 'Database connection closed.';
}
?>
Look at how much nicer that is to look at! Also note that instead of assigning the results to
a $row variable, we assign the results to a $post variable. Since we are dealing with posts
in WordPress database, it makes sense to name things this way. If you were querying an
orders table, you might assign the results to an $order variable, and so on. This is to give
some indication to yourself and anyone else who needs to review the code of what you are
actually dealing with.
Conclusion
In this particular adventure in our PHP and MySQL tutorial series, we took a look at the
four different ways to process query results. We looked
at mysqli_fetch_row, mysqli_fetch_assoc, mysqli_fetch_array,
and mysqli_fetch_object as ways to loop through your results and output them or
process them as needed.
In the last lesson we learned more about working with results from select
queries in MySQL. In other words, when we used PHP to build up a query and
send it to MySQL, MySQL then sent back a resource which could be massaged
by any of the four techniques we discussed to get access to the data contained
in the resource. So of all the MySQL commands such
as SELECT, INSERT, UPDATE, and DELETE, SELECT is the only one to return a
resource on success which requires further processing. The other commands
simply return either true or false on a successful query or failed query
respectively. In this episode, we’ll continue working with the database and build
on the prior lessons concepts. We’ll now start completing inserts, updates, and
deletes as well. Let’s get to it!
What Does A Query Return?
First off, let’s take a look at the different scenarios for what we can expect when actually
executing the query against MySQL. A query is either going to succeed or fail, and the
table here shows each of the possible 8 scenarios you may have.
Query Success Query Failure
What this tells us is that the SELECT is going to strictly follow the 5 step process which is to:
All other cases for INSERT, UPDATE, and DELETE, are only going to require 3 steps. Those
would be 1, 2, and 5 like so:
<?php
// 1
// open a connection
$dhost = 'localhost';
$duser = 'root';
$dpw = '';
$dname = 'bookmarks';
$connection = mysqli_connect($dhost, $duser, $dpw, $dname);
// 2
// define the query
// we'll pretend these are coming from a form via $_POST
$url = 'http://yahoo.com';
$name = 'Yahoo';
// 5
// close the connection
if(mysqli_close($connection) == true) {
echo 'Database connection closed.';
}
?>
Slick!This is a good example of being able to open one database connection at the top of
the page, run multiple queries as needed in the body of the page, then close the database
connection at the very end. In this example, ran this page two times. Once with the
variable values of $url = 'http://yahoo.com'; and $name = 'Yahoo';while the second
query contained $url = 'http://vegibit.com'; and $name = 'VegiBit';. Once the
connection was opened, we first did a query using the INSERT statement to put bookmark
into our links table. Further down the page, but before the database connection was
closed, we ran another query using the SELECT statement to immediately read back the
data we just inserted. Once we did all of this, we simply closed the database connection.
mysqli_insert_id
Typically when doing inserts into a MySQL database, you’ll have an ID field that auto
increments on each new insert. You never specify the value of this field, MySQL does it all
automatically for you. The problem however, is that this field is also typically the unique
identifier for a specific row or record of data in the table. How often do you hear something
like, find by ID? If you are entering new records into the database, and you’re not
specifying what their ID is, then how in the world will you find out this information? You’ll
find this out with the mysqli_insert_id() function, and it is a critical function to be aware
of. Maybe you need to do another insert into another table right after the first insert, and
you need to use the prior ID for this purpose. This happens all the time in relational
databases. The function signature is like so:
// 2
// define the query
// we'll pretend these are coming from a form via $_POST
// or from a link via $_GET
$url = 'http://google.com';
$name = 'The Google';
// create a new query to view the records to oberve if the updates took
$query = 'select * from links';
// 5
// close the connection
if(mysqli_close($connection) == true) {
echo 'Database connection closed.';
}
?>
The query worked perfect and we can see that Google is now The Google and 1 row
Note!
was affected.
// 2
// define the query
// we'll pretend these are coming from a form via $_POST
// or from a link via $_GET
$url = 'http://google.com';
$name = 'The Google Homepage';
// create a new query to view the records to oberve if the updates took
$query = 'select * from links';
// 5
// close the connection
if(mysqli_close($connection) == true) {
echo 'Database connection closed.';
}
?>
Conclusion
We’ve come full circle covering the basics of PHP and MySQL manipulation. We can see
it’s a pretty straight forward process to implement CRUD with native PHP and MySQL.
Now, using any of the awesome PHP frameworks to handle these chores for you is
certainly an option. In cases where you might have a client that has hosting that might not
support the latest and greatest technologies however, you’ll need to know how to do these
things by hand in PHP. For those scenarios, this PHP Tutorial Series is the answer to your
woes.
With all the talk about working with databases using MySQL and PHP in this
tutorial series, one thing we didn’t cover yet is SQL Injection and how to protect
your site from it. The syntax for MySQL is very specific, and if you don’t get it
right, it is easy to break. As we build up queries using dynamic data from our
variables in PHP, you need to be careful that any data contained in those
variables do not break the syntax as well. One of the main things to look out for
is the single quote in strings. In this episode we’ll talk a little bit about SQL
Injection, and the method used to combat it.
What Is MySQL Injection
SQL Injection is the process of a malicious hacker on the internets that purposely tries to
take advantage of the specific nature of SQL syntax, and the fact that it can be broken. If a
hacker is able to carefully put together an URL string, form data, or cookie data, to
nefariously inject their malicious SQL into yours, your database could become the victim of
dropped tables, stolen data, entire databases being dropped, or worse. The main idea is
that the hacker takes advantage of the ability of single quotes to denote starting and
ending points of SQL code. If those single quotes are not properly escaped, then they are
prone to this type of attack.
$status = "Hey buddy, you're on point today. Keep that stuff up.";
If we were inserting this into our database, it might look something like this:
insert into friends (status) values ( 'Hey buddy, you're on point today. Keep that stuff up.' );
The problem is that the single quote included in the string may cause a problem for
MySQL.
Solution
The solution to this problem is to simply escape the string like so.
insert into friends (status) values ( 'Hey buddy, you\'re on point today. Keep that stuff up.' );
addslashes($string)
It all started with the addslashes function some time in the past. This function takes a
string as it’s argument, and returns the string with any problem characters like a single
quote automatically escaped for you. This was a good idea, so good in fact, that it was
made a default baked into the language by way of something called Magic Quotes.
Magic Quotes
Magic Quotes is a configuration directive in PHP that would automatically call addslashes
on all GET, POST, or COOKIE data by default. The thinking was that this would save
developers the mistake of forgetting to do this on their own and open up their websites to a
security vulnerability. This was added in PHP2 and became the default in PHP3. All good
things come to an end however, and in PHP5.4 Magic Quotes were sent to the trash can.
Why you say? Well, it caused a lot of confusion for developers, and made programs much
less portable from host to host. This is because one never knew if the configuration was on
or off for Magic Quotes. So in some cases, the code would work just fine, and in others if
might fail altogether. There is a solution to these woes however.
$query = "Isn't it nice that we don't have to escape ' characters all by ourselves?";
echo $query.'<br>';
echo $escaped.'<br>';
?>
Note that when the query is first echoed out, it contains all of those problematic ‘
characters. In MySQL, strings must be enclosed by single quotes exclusively, so by putting
this string inside of single quotes, the query is now broken and dangerous to the database.
Also notice that once we run our query string through the mysqli_real_escape_string
function, it comes out crisp, clean, and safely escaped for use with the database.
What Is Guzzle?
Guzzle is an HTTP client built with and for PHP. The cURL software has typically handled
all of the HTTP heavy lifting in PHP, or in some cases of quick hacking, the good old
file_get_contents() function. Guzzle is a bit more advanced and simple at the same time.
The software itself is quite impressive, providing a nice elegant solution to the developer
that is easy to use. All the complexity is hidden away in the class implementation.
C:wampwwwguzzle>
Nice!If you made it this far, you now have a working copy of the Guzzle Software on you
local machine. Now you can test it out a bit.
require 'vendor/autoload.php';
use GuzzleHttpClient;
echo '<pre>';
print_r($response);
?>
Nice! We can see a ton of useful information about the response received right there.
require 'vendor/autoload.php';
use GuzzleHttpClient;
$statuscode = $response->getStatusCode();
$reasonphrase = $response->getReasonPhrase();
echo 'The get request to http://httpbin.org/get has a response with a statuscode of '.$statuscode.'
and a reasonphrase of '.$reasonphrase;
?>
$body = $response->getBody();
echo $body;
?>
{
"args":{
},
"headers":{
"Connection":"close",
"Host":"httpbin.org",
"User-Agent":"Guzzle/5.0.1 curl/7.36.0 PHP/5.5.12",
"X-Request-Id":"6af65b26-cd0f-4822-b923-e14f66590ea0"
},
"origin":"204.79.197.200",
"url":"http://httpbin.org/get"
}
What Is Goutte?
At the time of this writing, Laravel 5 development is in full swing – and there are
lots of changes coming down the pike. It would be fun to jump back in to
covering Laravel but things seem a little too fluid at the moment. We’ll know by
the end of the year where to focus our energies when working with Laravel
once the feature set and best practices are agreed upon and shipped. In the
meantime, let’s take a look at some of the various PHP repositories that might
be fun to tinker with. In this episode, we’ll take a look at Goutte which is written
by the legendary fabpot, or Fabien Potencier. Fabien is the creator of the well
known Symfony Framework which has components that are in use by many
projects in the PHP community.
Installing Goutte
To your own copy of the package to play around with, head on over to Packagist to find the
requirements for your composer.json file. Oh heck, no need, here it is for you:
{
"name": "fabpot/goutte",
"type": "application",
"description": "A simple PHP Web Scraper",
"keywords": ["scraper"],
"homepage": "https://github.com/fabpot/Goutte",
"license": "MIT",
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
}
],
"require": {
"php": ">=5.4.0",
"symfony/browser-kit": "~2.1",
"symfony/css-selector": "~2.1",
"symfony/dom-crawler": "~2.1",
"guzzlehttp/guzzle": "4.*"
},
"autoload": {
"psr-0": { "Goutte": "." }
},
"extra": {
"branch-alias": {
"dev-master": "2.0-dev"
}
}
}
// Check out the symfony.com subreddit and request the top posts from this month
$crawler = $client->request('GET', 'http://www.reddit.com/r/symfony/top/?sort=top&t=month');
// Use the symfony filter method to find all links which are children of paragraph
// elements which have a class of title then loop through the results using the each method
?>
200 OK
Introducing the Official Symfony Best Practices
New in Symfony 2.6: Bootstrap form theme
New in Symfony 2.6: AJAX requests in the web debug toolbar
New in Symfony 2.6: Farewell to ICU component (Symfony Blog)
New in Symfony 2.6: LockHandler
Symfony 2.5.5 released
New in Symfony 2.6: Date support for Validator constraints
Commerce Guys makes big investment in Symfony, for eCommerce and Platform.sh
Symfony, 9 years of history, rewards its top 150 contributors
Let’s revive Symfony Montreal meetups!
New in Symfony 2.6: Smarter assets:install command
Symfony 2.6 fast approaching its stabilization phase
New in Symfony 2.6: New shortcut methods for controllers
A week of symfony #406 (06->12 October 2014)
Tell Doctrine to use a different database user when using the symfony console?
Symfony 2.4.10 released
A week of symfony #407 (13->19 October 2014)
Awesome!With the Goutte software we were able to fetch all the links from the Symfony
subreddit.
Goutte vs SimpleHtmlDom
Simple HTML Dom is another handy piece of software for doing tricks like this. It is a bit
easier to use than Goutte, however if you learn all the details of how Goutte works, it may
help with your Symfony chops. In dealing with Laravel, which relies on several Symfony
dependencies in order to work, many have become more interested in what Symfony has
to offer.
?>
angular/angular.js
jashkenas/backbone
emberjs/ember.js
knockout/knockout
tastejs/todomvc
spine/spine
Polymer/polymer
mozbrick/brick
facebook/react
Try it out for yourself! You can try your credentials as well on your own setup and see
Epic!
how to navigate the site via PHP. We’re not sure what the use case for this would be, but
nonetheless, it’s pretty impressive and a testament to the power of the software.
Conclusion
In this episode, we took a look at Goutte, the powerful combination of Guzzle and Symfony
Components such as Browser Kit, Css Selector, and Dom Crawler. It’s fun to play around
with these tools for learning purposes, and no doubt forces you to dig into the structure of
the DOM, which is sometimes a little tricky.
One of the great things about PHP is the fact that it has built in functions for
anything and everything. A really neat thing to do is to try to stitch these
functions together to create interesting new functions. If there are functions in
PHP that you really like and want to extend them so to speak, you can do this
by creating your own. In this episode, we’ll take a look at doing just that. We’ll
have a look at preg_match_all, array_count_values, and arsort, to create a
new and awesome function named preg_count_sort. Let’s check it out.
array_count_values
This function takes an array as input, then counts the number of times each value happens
in the provided array. It then creates a new array, with the keys of the new array being the
original values, and the values now containing a count of how many times the original
value appeared in the original array.
arsort
There are a tremendous amount of array functions in PHP so you can find whatever you
need for sorting. This one sorts the provided array in reverse order and keeps the original
keys in tact, which we need for our little application here.
preg_count_sort
Here is the source code for the function.
function preg_count_sort( $pattern, $subject ) {
$result = array_count_values($matches[0]);
arsort($result);
Let’s talk about how it works. First off, we simply define the function by using
the function keyword followed by the name of the function we wish to declare. Note that
this function takes a pattern, which will be a regular expression, and a subject, which will
be the data against which the regular expression will run. Next up, we open up a table tag
since we are going to put the results of our function into a nice tabular output. On the next
line we make use of the first of the original PHP functions, preg_match_all. This function
takes the regular expression pattern as the first parameter, the subject to match against as
the second, and the name of the array to hold any matches as the third. Note that we
include the starting and ending delimiters for the pattern by including the forward slash at
the beginning and end of the pattern. This way, when we provide the regular expression in
our application, we don’t have to also provide the beginning and ending
delimiters. array_count_values is the second native php function to make use of. This
counts the number of times each match occurred in the matches array which the
preg_match_all function populated. Once we have the count of matches, we use the third
native PHP function arsort, to sort the counts from highest to lowest in number. The
foreach loop simply loops through all the matches placing them into rows and cells within
the overall table. Lastly, we just go ahead and close out the table tag.
<body class="container">
<?php
?>
<br>
<strong>Subject</strong><br>
<form action="preg_count_sort.php" method="post">
<textarea type="text" name="subject" cols="100" rows="5"><?php if(isset($subject))echo
htmlentities($subject); ?>
</textarea>
<br>
<strong>regular expression pattern</strong><br>
<input name="pattern" type="text" size="100" value="<?php if($pattern) echo $_POST['pattern']; ?>">
<br>
<br>
<button type="submit">Preg Count Sort</button>
</form>
</body>
</html>
So what does this little app do for us? Well, we can test it out. Let’s define our Subject and
pattern, then run the program.
Our subject will be this text string: “If you like apple products, you might have an iPad,
iPhone, or even an iMac. If the macbook pro is not your thing, you might like the Lenovo
Carbon X1. The latest generation iMac is fantastic, however the decade old iMac sitting on
my desk is more of a collectors item at this point. No need of a new iPad yet, the original
retina display version still works just fine.”
Our pattern will be this expression: i[A-Z][a-z]*
Here is the result when we run the program
When we ran the function, we found that in the subject iMac occured 3 times,
Pretty Cool!
iPad occurred twice, and iPhone occurred once. Of course this is a bit of a nonsense
example, however if you brush up on your regular expressions and provide a lengthy
meaningful subject, you can uncover all kinds of interesting data.
Conclusion
This quick episode took a look at combining PHP functions together to create your own. If
you use your imagination, you can take this approach with any number of functions which
accept and output data to create your own custom made solutions.
Most likely you have come across Regular Expressions at some point during
your software development. Regular expressions are one of those things that
tend to make people take sides and form strong opinions. Some swear by their
use, while others have a deep disdain for them. Either way, they are a
necessary evil – we need to learn about them in order to round out our skills so
to speak. In this episode, we’ll take a quick look at some of the basics in getting
up and running with regular expressions. We’ll also build a fun one page PHP
application to test our own regular expressions with. Let’s jump right in.
Metacharacters
At this point its good to mention the special characters in regular expressions. Here is a
table of them.
Metacharacter Meaning
+ match 1 or more
We have a nice little overview of what all these characters do. Fear not, if they
Fantastic.
mean nothing right now, they will make more sense as we move on.
Since these characters above have special meaning, if you are trying to match them in a
string, you must escape the character in your regular expression. Consider the string Do
you know what 2 + 2 is equal to? {we will soon find out} [haha]. If we apply the regular
expression /2 + 2/ it fails. If we try /2 + 2/ it now works. Again, this is because the plus
sign is a special character so it must be escaped with the backslash character. What if we
need to match that text in between the curly braces? You might think that /{[a-z ]*}/ but
it does not, we must again escape the special characters like so /{[a-z ]*}/ and now it
works.
The best thing to do is to simply paste in various subjects and patterns and have a
Slick!
play for yourself. If you need all the nitty gritty on character classes head right here.
Of course like a good hacker, this is the only pattern of regex I use when hacking in a
playground environment, but seriously folks, careful with the big guns.
Greed is Good
Greed is good, or so said some nutjob on wall street many moons ago. Speaking of wall
street, did you see that movie with that dude from the Titanic? Great flick, those guys were
crazy. Anyhoo… In regular expression we have this concept of greediness. What it means
when something is greedy in the regex sense, is that it will try the match as many times as
it possibly can before it stops matching. If there is anything that can trip you up when
working with regular expressions, it is definitely greediness vs laziness. When is a
particular token greedy? When is it lazy? How does this affect the pattern I am trying to
use? You’ll need to take all of these things into consideration when building your own
patterns. Beyond rote memorization, which does have it’s merits, it is usually a matter of
visiting a tool like regexr and simply testing out the various quantifiers to see what works.
Let’s see an example of greediness in action. We’ll make use of this pattern /w/ which be
reminded is a word character and is greedy. This is the result on our test string, note that it
matches every single word character in the string.
Ok, pretty neat. You can see we find any sequence of 3 characters in a row and it works
pretty well. Now, lets change it up. Lets find three characters *only* if they are followed by
a curly brace like this }. How can we do such a thing? We can do it with the positive
lookahead just like this.
You see that partner? Very cool – a match is found and the delimiter, or the specified
character of the positive lookahead, is not contained in the match. This is immensely
useful! Once again, (?=) is the syntax for a positive lookahead.
Positive Lookbehind
We can do the same thing for matching patterns in instances where we would like to look
*before* the main pattern for a specific piece of text or a specific character. This is the
positive lookbehind. We’ll modify our regex to match only 2 word characters in a
row *only* if they are preceded by a curly brace like this {. This can be accomplished with
the pattern of (?<={)[a-z]{2} which will match we in the string Do you know what 1 + 1 is
equal to? {we will soon find out} [haha]. Note that (?<=) is the syntax for the positive
lookbehind.
Negative Lookahead
The inverse of the positive lookahead and lookbehind are the negative lookahead and
lookbehind. These are the exact opposite of the prior examples. Basically, only match the
given pattern if it is *not* followed by or preceded by a given character or string. For
example, if we want to find all groups of 3 characters *only* if they are not followed by a
curly brace like this }, we can do that.
Ah, yes. Look at that. Ain't she a thing of beauty? All of those nice three character
combinations, but wait, look at that out right before the curly brace. It is not highlighted as
a match. Yes that's right, that's due to the negative lookahead. Note that the syntax for the
negative lookahead is (?!) where the thing that you do not want to match comes after the
exclamation point.
Negative Lookbehind
Just like we have a negative lookahead, we have a negative lookbehind, and the syntax for
this is (?<!) where the thing that you do not want to match comes after the exclamation
point.
Conclusion
Regular expressions are dry stuff folks, much like the Mojave. In fact, the more outlandish
the writing, the more boring the topic being covered. At about 1900 words, that's just about
all I can muster for regular expressions today. I think we covered some good starting
points for regular expressions in this episode. They may be a bit dry, but they are
immensely powerful, and when you need them, they just might be the only way to solve a
difficult string or character related problem. Tune in again when we build our very own
regular expression application in our very next episode!
As promised, in this episode we will build our very own regular expression
tester so we can test out various regex patterns. As we covered in the prior post
on regular expressions, there are many great tools to do this online as well. So
what is the reason to build our own? It’s simple really, it’s fun to do and a great
learning exercise too. What we’ll set out to do is build a simple one page
application that accepts a string of data, or subject, as well as a pattern. We’ll
then have a submit button that will run the pattern against the subject using
the preg_match_all function build into PHP. Let’s check it out.
So in this snippet there are a few things to note. We’re simply going to post the form
to preg_match_all.php which is the name of the one file in this application. We include a bit
of code to check for the presence of data that may have been submitted via the form. If it
has, we repopulate the form with those values. This way, we don’t have to continually
paste back in the data that we’re testing against for the subject. This also helps for the
pattern since we can make incremental edits to the pattern easily and continue to test
against the subject in question. Finally we include a simple submit button, which we’ve
addressed with the text, “Preg Match All”. It looks like this.
Cool. We can see there is a text area to input some data that we want to check against, a
text input for the regular expression pattern, and a simple submit button.
if (strlen($pattern) > 0) {
preg_match_all('/' . $pattern . '/', $subject, $matches);
foreach ($matches[0] as $match) {
echo $match . '<br>';
}
}
?>
First, we use the ternary operator to check for data submitted via the form. If there
Excellent.
has been no data submitted, we simply enter an empty string into the $subject and
$pattern variables.
Next up, we use a simple if statement to check the length of the $pattern using
the strlen function. If the $pattern has a length that is greater than zero, then we proceed
to run the preg_match_all function using the data that had been submitted from the
form. preg_match_all is a fantastic function you can use to check for all matches within a
subject. The first parameter to this function is the actual pattern to use for the regex. Note
that in the code above, we added the delimiters ahead of time, that way when we enter the
pattern in the form we don’t need to include them. This is just a simple convenience
mechanism. The second parameter is the subject that we will test the regular expression
against. This is the data that comes in from the textarea in our form. The third parameter is
named variable to hold the matches that result from the regular expression being run.
With preg_match_all, the matches actually get stored in a multi dimensional array. This is
why when we loop over this array, we loop over $matches[0] and not $matches. Finally, we
simply echo out each match followed by a line break. The entire script looks like this.
<html>
<head>
<meta charset="utf-8">
<link href="css/bootstrap.min.css" rel="stylesheet">
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script src="js/bootstrap.min.js"></script>
</head>
<body class="container">
<?php
if (strlen($pattern) > 0) {
preg_match_all('/' . $pattern . '/', $subject, $matches);
foreach ($matches[0] as $match) {
echo $match . '<br>';
}
}
?>
<br>
<strong>Subject</strong><br>
This is super simple and basic, but it should make for a nice quick and dirty testing tool for
some of our regular expressions. Let’s examine positive and negative lookbehinds. Recall
from our prior post that this is when the regular expression looks behind, or before, the
pattern in question. This is good for matching something that only is preceded by a
particular character or string of characters. Here is a screenshot or our tool completing a
successful positive look behind match.
This is right after the submit button had been clicked. We can see the match of ‘we’ gets
output at the very top, and our form is populated with the data we had used. This way we
can easily edit the data in the form, and try another test. This used Do you know what 1 +
1 is equal to? {we will soon find out} [haha]. for the subject and our regex pattern
was (?<={)[a-z]{2}. This pattern says, match any two characters within the range of lower
case a to z, *only* if it is preceded by a left curly brace. Nice!
Let's now test the negative lookbehind. We can modify the pattern to (?<![)[a-z]{4}which
says to match any four sequential characters as long as there is not a left bracket before
them. We can see here that this works, as the string 'haha' was not matched, but several
other consecutive four characters were.
Conclusion
Should you now ever find yourself without an internet connection and unable to reach any
of the fine resources we covered in the last episode to test your regular expressions, you
now have a really simple way to test them locally if need be. It's quick, dirty, and useful -
perfect if you ask me
• http://php.net/-manual/en/tutorial.php
• http://php.about.com-/od/learnphp/ss/phpbasics.htm
The beginners guide to programming in PHP
found at about is a very solid introduction to the language, how it is used, and how
you can learn it quickly. This 9 part series is perfect for the beginner learning PHP.
• http://w3schools.com/-php/
• http://tutorials-point.com/php/
Tutorials point is a great site with the motto of,
“Simply Easy Learning.” They take this approach to explain the nature of working
with PHP as a beginner to get up to speed and build you base with PHP.
• http://code.tutsplus.com/-tutorials/the-best-way-to-learn-php–net-22287
• http://codeproject.com/-Articles/759094/Step-by-Step-PHP-Tutorials-for-Beginners-Creating
Codeproject is another high quality site to help
with your adventures in PHP. This article take you through creating a new program
from scratch, with authentication, membership roles, and create read update delete
functions.
• http://lynda.com/-PHP-training-tutorials/282-0.html
• http://codecademy.com/-tracks/php
Codecademy once again makes the list as they
are one of the best ways to learn with hands on exercises right in the browser. They’ll
teach you to program in PHP the widespread programming language that is
everywhere, even on huge sites like Facebook.
• http://speckyboy.com/-php-tutorials-for-beginners/
• http://devzone.zend.com/-php-101-php-for-the-absolute-beginner/
Zend has done more for PHP than anyone else.
They provide a dedicated Zend server, Zend Studio, and professional level
enterprise PHP training. Thankfully, they also provide a fantastic series titled PHP
For The Absolute Beginner. This is another fantastic resource to add to our list.
• http://w3resource.com/-php/php-home.php
• http://webmonkey.com/-php_tutorial_for_beginners/
Webmonkey is another oldie but goodie from
the fine folks over at Wired Magazine. Webmonkey notes that although simple, PHP
is powerful and fits in perfectly with the even more basic language of the web, HTMl.
Webmonkey’s PHP Tutorial For Beginners is a perfect addition to your collection.
• https://css-tricks.com/-php-for-beginners-building-your-first-simple-cms/
• https://www.codeofa-ninja.com/-php-and-mysql-crud-tutorial.html
Finally, we have the code of ninja – because
who doesn’t want to be a Ninja?! In this article, you’ll learn everything a beginner
needs to know to get up to speed with PHP.
Go ahead and download the package, unzip the contents and launch your Eclipse PDT
software. Once you have downloaded and installed your software, you still have to install
and configure a debugger in the IDE. There are a few ways to do this and it can be
frustrating the first time you attempt it, but outlined here is the easiest method to install the
debugger and get ready to step through some code. First you will navigate to
Window->Preferences->Install/Update->Available Software Sites.
Once there you will need to click Add, then put in the details as follows:
Name: PDT
Location: http://downloads.zend.com/pdt
Now you will navigate to Help->Install New Software and choose your newly added
download location from the dropdown menu, then choose the Zend Debugger Feature, hit
next and follow the prompts. Restart the IDE when asked.
We’re almost there and ready to start debugging and learning some snippets of code but
first we need to configure our debug configurations. First create a new PHP project named
‘test’ by way of File->New->Local PHP Project and create a simple index.php file in the
project. Once you have done this add the following code snippet to your index.php file.
<?php
echo '<pre>';
$vegibit = array(
"learn" => "PHP",
"read" => "vegibit.com",
);
print_r($vegibit);
?>
Let’s now configure our debugger by choosing Run->Debug Configurations. In this window
you will choose PHP Script as a CLI Application, Alternate PHP for your installed PHPs
and browse for the index.php file you just created in your project named ‘test’. In the name
field we’ll simply call this instance of the debugger ‘debug it!’. Apply all settings once
complete. Here is a screenshot of the settings.
Ok friends, let’s get debugging! Now that we have our project created, our debugger
installed and configured, as well as the snippet of code provided saved in our index.php
file, we can launch the debugger. There are several ways to do this in the IDE but we’ll
choose the bug icon in the toolbar to launch this one. You will then be prompted for a PHP
to Debug Perspective Switch, choose Yes.
This is where the fun starts as your code launches and stops at the very first line. We can
now step into each and every line of code to debug exactly what it is doing. This gives us
incredible insight into how our code works rather than the constant placement of print_r
and var_dump statements in our PHP files. Below is what the IDE will look like as the code
executes and stops at line 2. The IDE shows you all of the environment variables, console,
and browser output, among many others.
Now click on the Step Into icon or F5 key two times slowly to watch a pre tag get echoed
out for nice formatting, as well as see an array named $vegibit get created with the keys of
learn and read as well as the values of PHP and Vegibit.com. Observe your newly created
variable in the variables window in memory before these values are even sent to the
screen! Pretty slick!
Finally click on Step Into one more time and finish the execution of the script to view the
final output.
Now you have a debug environment that you can use to debug any snippet of PHP code
you like. A great way to learn is to simply go to php.net and copy one of the many samples
of code into your index.php file of your test project, save, and debug it the very same way
we just did here. You can now step through any piece of code you can find and learn
exactly what it does line by line in real time! Fun stuff indeed.
?>
Just like that we have an array which is now stored in the $houses variable. Great, so how
do we get information out of our array now? Well, lets try to echo out the information in that
array like we have been doing with all of the other variable types up until now.
<?php
echo $houses;
?>
echo $houses[0].'<br>';
echo $houses[1].'<br>';
echo $houses[2].'<br>';
echo $houses[3].'<br>';
?>
Colonial
Contemporary
Southwestern
Metro
Now we’re seeing how to grab the info out of the variable. So at index zero we have
Nice!
our Colonial, index 1 has a Contemporary, index 2 Southwestern, and index 3 has a Metro.
With arrays you can store as many values as you need to, maybe you have 500 emails
you want to store in a variable, with an array you can do that no problem.
echo $dynamic[0].'<br>';
echo $dynamic[1].'<br>';
echo $dynamic[2].'<br>';
?>
7
House
Car
First, we assigned a bunch of values to our new dynamic array. At index 0 we
Excellent.
placed a number in, specifically an integer. At index 1 is a string. Index 2 is also a string.
Note that in the third index is an array. Well how about that America, an array within an
array. Yes You Can! Consider this an introduction to multi-dimensional arrays. Having an
array within an array requires us to put on our thinking cap. We saw how to get at the data
contained in simple array, now how do we deal with this type of thing. Let’s see.
<?php
echo $dynamic[0].'<br>';
echo $dynamic[1].'<br>';
echo $dynamic[2].'<br>';
echo '<br>';
echo $dynamic[3][0].'<br>';
echo $dynamic[3][1].'<br>';
echo $dynamic[3][2].'<br>';
?>
7
House
Car
grass
mower
mulch
When there is an array within an array, you need to level up partner. That is, you
Fantastic!
need to get to the next level. Notice how we use the double bracket notation to dig deeper
into that array within an array [][]. What is this doing for us? Well you see, in the first
bracket, we need to specify where we want to look. In this case we want to look at position
3 since that is where the second array lives which we want to peer into. Ok, great – now
just repeat the process. Now that you’ve specified the third position of the first array, what
position of the second array do you want to access? Put this value in the second bracket.
This is how you access arrays inside of arrays and this is what you call a multi dimensional
array. You are not limited to only two levels either. You can have arrays within arrays
within arrays, however you will begin to drive yourself mad if you nest these things to
excess. A good rule of thumb is to try and mimic real data configurations that you might
find in the real world. Just for kicks though, let’s put one more array within an array to test
it out.
<?php
$dynamic = array(7, 'House', 'Car', array('grass', array('John Deere', 'Kubota', 'New Holland'),
'mulch'));
echo $dynamic[0].'<br>';
echo $dynamic[1].'<br>';
echo $dynamic[2].'<br>';
echo '<br>';
echo $dynamic[3][0].'<br>';
echo $dynamic[3][1][0].'<br>';
echo $dynamic[3][1][1].'<br>';
echo $dynamic[3][1][2].'<br>';
echo $dynamic[3][2].'<br>';
?>
7
House
Car
grass
John Deere
Kubota
New Holland
mulch
Excellent. See how now that there is an array inside an array inside an array, we just use
triple bracket notation [][][] to get at that data. Is there really a need to go this many
levels deep? Not a lot, but it does help to know how this stuff clicks together, much like our
beloved sophisticated interlocking brick system (Legos).
$dynamic = array(7, 'House', 'Car', array('grass', array('John Deere', 'Kubota', 'New Holland'),
'mulch'));
print_r($dynamic);
echo '<pre>';
print_r($dynamic);
?>
Array ( [0] => 7 [1] => House [2] => Car [3] => Array ( [0] => grass [1] => Array ( [0] =>
John Deere [1] => Kubota [2] => New Holland ) [2] => mulch ) )
Array
(
[0] => 7
[1] => House
[2] => Car
[3] => Array
(
[0] => grass
[1] => Array
(
[0] => John Deere
[1] => Kubota
[2] => New Holland
)
Notice here that we use the print_r() function a couple of times. The difference is that the
second time, we wrap the output in html pre tags. The pre tags provide a nice formatted
output so that it is easier to see how things nest within the array. See how each time we
reach another array, the output is indented to give us a visual indication that something
interesting is happening here. Put that print_r() function in your back pocket, you’re
going to use it all the time when debugging your code. There is one thing to be aware of
when retrieving data out of your arrays, and that is you need to specify an index that
actually exists or you’ll get an error.
<?php
$dynamic = array(7, 'House', 'Car', array('grass', array('John Deere', 'Kubota', 'New Holland'),
'mulch'));
echo $dynamic[4];
?>
$dynamic = array( 7, 'House', 'Car', array('grass', array('John Deere', 'Kubota', 'New Holland'),
'mulch'));
$dynamic[] = 'Bike';
echo $dynamic[4];
?>
Bike
By simply assigning a new value to the variable $dynamic[] using the bracket notation,
PHP knows that you want to add something to the end of the array. Note that you didn’t
even have to indicate that it was position 4 where you wanted to place something, it just
did it for you. Just to bring the idea home, let’s look at one more example.
<?php
$dynamic = array( 7, 'House', 'Car', array('grass', array('John Deere', 'Kubota', 'New Holland'),
'mulch'));
$dynamic[] = 'Bike';
echo '<pre>';
print_r($dynamic);
?>
Array
(
[0] => 7
[1] => Big House
[2] => Car
[3] => Array
(
[0] => grass
[1] => Array
(
[0] => John Deere
[1] => Kubota
[2] => New Holland
)
This is a neat example here. See how we can easily overwrite and existing index by simply
assigning a new value to it. This is why index 1 no longer has a House in it, but a Big
House in it. Suppose that you need to add something at a specific position, we did that as
well. Note that index 9 now has a Surf Board in it.
Associative Arrays
We’re getting a good handle on arrays in PHP, but we’re not done yet. So far we have
been working with plain old vanilla index based arrays. The standard index based array
relies on numeric keys to work with them. The keys are often invisible to us until we
actually output the full array using a pretty print. Associative arrays are a little different in
that the keys must be specified explicitly using a label of some type. Think of it like a
collection of file folders with labels on them. The label on the folder is the key, while the
contents located inside of the folder is the value. The easiest way to see how this works is
to simply look at some code.
<?php
$dynamic = array( 'number' => 7, 'live' => 'House', 'drive' => 'Car', array('mow' => 'grass',
array('tractor' => 'John Deere', 'tractor2' => 'Kubota', 'tractor3' => 'New Holland'), 'landscape' =>
'mulch'));
echo '<pre>';
print_r($dynamic);
?>
Array
(
[number] => 7
[live] => House
[drive] => Car
[0] => Array
(
[mow] => grass
[0] => Array
(
[tractor] => John Deere
[tractor2] => Kubota
[tractor3] => New Holland
)
Nice Work!We have turned our formerly boring standard array into a fully associative array.
Now we can access this data using named keys of some type instead of only numeric
indices. To be fair, all we did was a pretty print of the contents so let’s look at the actual
syntax we would need to use to access all of this information.
<?php
$dynamic = array( 'number' => 7, 'live' => 'House', 'drive' => 'Car', array('mow' => 'grass',
array('tractor' => 'John Deere', 'tractor2' => 'Kubota', 'tractor3' => 'New Holland'), 'landscape' =>
'mulch'));
echo $dynamic['number'].'<br>';
echo $dynamic['live'].'<br>';
echo $dynamic['drive'].'<br>';
echo $dynamic[0]['mow'].'<br>';
echo $dynamic[0][0]['tractor'].'<br>';
echo $dynamic[0][0]['tractor2'].'<br>';
echo $dynamic[0][0]['tractor3'].'<br>';
echo $dynamic[0]['landscape'].'<br>';
?>
7
House
Car
grass
John Deere
Kubota
New Holland
mulch
Slick!See how instead of putting the number of the index in between the brackets, we now
put in the label, whatever that may be. Note that for arrays within arrays, you might need to
use a combination of index based and associative labels to get at the data you are looking
for just like we did above.
Wrapping Up
We have the basics of PHP arrays covered. Use this and other examples to refine your
skills. Soon we will dig into all of the amazing functions for dealing with arrays that PHP
provides to us, and there are many!
The Top 17 Most Popular PHP Array
Functions
You are going to run into PHP Arrays and PHP array functions with amazing
regularity during the course of your web design and web development. It makes
sense, because arrays are one of the most useful data types we can use. So it
got us to thinking, what would you get if you combined the worlds most
popular PHP CMS applications and dumped all of their source code into one
bucket, then analyzed their most used array functions? Well you would get this
awesome list of course! This is a great way to keep your skills sharp or simply
refreshed when working with Arrays in PHP. Let’s check it out.
• 1array()
• 2is_array()
• 3in_array()
• 4array_merge()
• 5array_keys()
• 6array_key_exists()
• 7array_shift()
• 8array_push()
• 9array_pop()
• 10array_values()
• 11array_map()
• 12array_unique()
• 13array_slice()
• 14array_diff()
• 15array_search()
• 16array_reverse()
• 17 array_unshift()
1. array()
This handy little guy creates an array for you. Here we’ll create an associative array with
two keys, and then place an an associative array inside one and an indexed array inside
the other.
<?php
$array = array (
'websites' => array (
'Search' => 'Google',
'Social' => 'Facebook',
'News' => 'NY Times'
),
'friends' => array (
'Chris',
'Jim',
'Lynn',
'Jeff',
'Joanna'
)
);
print_r ( $array );
?>
)
Learn more about array() at http://us1.php.net/manual/en/function.array.php
2. is_array()
Checks whether the variable is an array. Returns TRUE if the variable is an array, and
FALSE otherwise. Used like so:
<?php
echo is_array($array); //1 or TRUE
?>
3. in_array()
We may often want to check if a certain value is in one of our arrays. Recall from our
example above that we assigned an indexed array of friends to the ‘friends’ key of our
example array. Let’s see if ‘Jeff’ was included.
<?php
$result = in_array('Jeff', $array['friends']);
Ah ha, turns out he was. With in_array(), the first argument is what you are looking for,
and the second argument is the array you will check in. Learn more
about in_array() at http://us3.php.net/manual/en/function.in-array.php
4. array_merge
Remember we had some websites and friends in the array from the prior example. In fact
we stored an array of values in those arrays. Well I’m feeling lazy and I don’t want to work
with two arrays. I just want to work with one, so let’s merge those two arrays together!
<?php
$array = array (
'websites' => array (
'Search' => 'Google',
'Social' => 'Facebook',
'News' => 'NY Times'
),
'friends' => array (
'Chris',
'Jim',
'Lynn',
'Jeff',
'Joanna'
)
);
print_r ( $merged );
?>
And bingo bango, we now have one array created out of two!
Array
(
[Search] => Google
[Social] => Facebook
[News] => NY Times
[0] => Chris
[1] => Jim
[2] => Lynn
[3] => Jeff
[4] => Joanna
)
5. array_keys
Let’s now extract all the keys from our $merged array by adding these lines:
<?php
$keys = array_keys ( $merged );
print_r ( $keys );
?>
And now you can see the keys of our $merged array become the values of the array
returned from array_keys()!
Array
(
[0] => Search
[1] => Social
[2] => News
[3] => 0
[4] => 1
[5] => 2
[6] => 3
[7] => 4
)
6. array_key_exists()
With array_key_exists() we can perform a validation similar to the way we would
with isset(). You pass a key to search for and an array to search in, and the function will
return TRUE if the key exists in the array provided. Building on our prior example, let’s see
if the 7th key is set:
<?php
$keys = array_keys ( $merged );
$exists = array_key_exists('7', $keys);
7. array_shift()
Let’s remember our original $array which had two keys in it, ‘websites’ and ‘friends’. I want
each key to have it’s own variable name in the program, how can I do that? Well, let’s
apply the array_shift() function to $array, return the result to a variable $shifted, and
examine both variables.
<?php
$array = array (
'websites' => array (
'Search' => 'Google',
'Social' => 'Facebook',
'News' => 'NY Times'
),
'friends' => array (
'Chris',
'Jim',
'Lynn',
'Jeff',
'Joanna'
)
);
$shifted = array_shift ( $array );
print_r ( $array );
print_r ( $shifted );
?>
You can see the ‘websites’ key, which is the first in the array, was shifted out of the array,
while the ‘friends’ key was left intact. Awesome!
// print_r ( $array ); 'friends' is still in the original
Array
(
[friends] => Array
(
[0] => Chris
[1] => Jim
[2] => Lynn
[3] => Jeff
[4] => Joanna
)
)
// print_r ( $shifted ); 'websites' was shifted out
Array
(
[Search] => Google
[Social] => Facebook
[News] => NY Times
)
8. array_push
Our newly created $shifted variable is mad. It wants back into the original $arrayvariable
to undo the shifting we have caused. Well, let’s try to apply the array_push()function to the
original $array and push $shifted back onto the end of the array:
<?php
$array = array (
'websites' => array (
'Search' => 'Google',
'Social' => 'Facebook',
'News' => 'NY Times'
),
'friends' => array (
'Chris',
'Jim',
'Lynn',
'Jeff',
'Joanna'
)
);
print_r ( $array );
?>
You can see friends is now in the first position and the $shifted array is added back to the
original array. Note that array_push() does not keep key => value pairs intact! We have
lost our ‘websites’ key(it is now 0).
Array
(
[friends] => Array
(
[0] => Chris
[1] => Jim
[2] => Lynn
[3] => Jeff
[4] => Joanna
)
9. array_pop
Fickle mister $shifted is mad about losing his ‘websites’ key. I’m not going to be in
this $array if I can’t have my original key. Ok fine then, we’ll array_pop() you right off the
end of this $array one more time.
<?php
$array = array (
'websites' => array (
'Search' => 'Google',
'Social' => 'Facebook',
'News' => 'NY Times'
),
'friends' => array (
'Chris',
'Jim',
'Lynn',
'Jeff',
'Joanna'
)
);
print_r ( $array );
print_r ( $shifted );
?>
And there you go mister $shifted – popped off and placed back into your own array.
Array
(
[friends] => Array
(
[0] => Chris
[1] => Jim
[2] => Lynn
[3] => Jeff
[4] => Joanna
)
Array
(
[Search] => Google
[Social] => Facebook
[News] => NY Times
)
10. array_values
Remember when we created the $merged array earlier and we got a nifty little array looking
like this?
Array
(
[Search] => Google
[Social] => Facebook
[News] => NY Times
[0] => Chris
[1] => Jim
[2] => Lynn
[3] => Jeff
[4] => Joanna
)
Well, I’m not crazy about the fact that some of those keys are named and others are
indexed. I’d like to grab just the values of the $merged array listed only with numeric
indexes. Let use the array_values() function to do just that.
<?php
$array = array (
'websites' => array (
'Search' => 'Google',
'Social' => 'Facebook',
'News' => 'NY Times'
),
'friends' => array (
'Chris',
'Jim',
'Lynn',
'Jeff',
'Joanna'
)
);
print_r ( $merged );
?>
Ah yes, there she is – my nicely formatted merged array with neat indexes 0 – 7 courtesy
of array_values().
Array
(
[0] => Google
[1] => Facebook
[2] => NY Times
[3] => Chris
[4] => Jim
[5] => Lynn
[6] => Jeff
[7] => Joanna
)
Learn more about array_values() at http://us3.php.net/manual/en/function.array-
values.php
11. array_map
Ok all this array business has me needing a break. Let’s go shopping and buy some cool
new gadgets, maybe a new iPad Air. You know, these days they tax you on everything, so
when we go shopping, let’s not forget that we have to pay a 5% sales tax. We’ll use
our array_map() function to help us there.
<?php
function salestax($price) {
return number_format ( ($price * 1.05), 2, '.', '' );
}
$items = array (
100,
50,
250,
70,
500
);
$finalcost = array_map ( 'salestax', $items );
print_r ( $finalcost );
?>
Ok check it out. We had our array of $items to shop for, but we needed to quickly calculate
the sales tax for each item at a 5% rate. Well with array_map() we can apply a function to
every single array element, and return an array with the newly processed results, in this
case our $finalcost – neat!
Array
(
[0] => 105.00
[1] => 52.50
[2] => 262.50
[3] => 73.50
[4] => 525.00
)
12. array_unique
You know there is a lot of blogging going on out there, and the search engines want to
make sure they only index unique articles. Our little internet spider came across some
articles below and put them into the $index. We need to make sure they are unique
however, maybe we can use array_unique() to help us out!
<?php
$index = array (
'How to Eat Apples',
'Surfing Safely in a Wave Pool',
'The Best Foods For Breakfast',
'How to Eat Apples',
'25 tips to blogging nirvana',
'The Best Egg Nogg Recipe for the Holidays'
);
$unique = array_unique ( $index );
print_r ( $unique )
?>
Awesome! Working as designed! Our array_unique() got rid of that duplicate value in the
array and returned us a new array with only unique titles. Did you spot the duplicate title in
the original array?
Array
(
[0] => How to Eat Apples
[1] => Surfing Safely in a Wave Pool
[2] => The Best Foods For Breakfast
[4] => 25 tips to blogging nirvana
[5] => The Best Egg Nogg Recipe for the Holidays
)
13. array_slice
Come to think of it, rather than use that array_unique() on our $index, let’s go ahead and
perform some surgery on that array and extract only the inner elements, leaving the first
and last entry to their own devices.
<?php
$index = array (
'How to Eat Apples',
'Surfing Safely in a Wave Pool',
'The Best Foods For Breakfast',
'How to Eat Apples',
'25 tips to blogging nirvana',
'The Best Egg Nogg Recipe for the Holidays'
);
$surgerized = array_slice ( $index, 1, 4 ); //slice it
print_r ( $surgerized );
?>
And there you have it, by passing the array to work on, the starting offset, and the length of
our extraction, we have successfully removed the middle 4 entries of our 6 element array.
Bravo!
Array
(
[0] => Surfing Safely in a Wave Pool
[1] => The Best Foods For Breakfast
[2] => How to Eat Apples
[3] => 25 tips to blogging nirvana
)
14. array_diff
Ok friends, our internet spider has been busy and it has created an updated index after
some time. We’d like to examine our first index in comparison to the second and see
what’s new. Let’s do it with our array_diff() function!
<?php
$index = array (
'How to Eat Apples',
'Surfing Safely in a Wave Pool',
'The Best Foods For Breakfast',
'How to Eat Apples',
'25 tips to blogging nirvana',
'The Best Egg Nogg Recipe for the Holidays'
);
$index2 = array (
'How to Eat Apples',
'Surfing Safely in a Wave Pool',
'The Best Foods For Breakfast',
'How to Eat Apples',
'25 tips to blogging nirvana',
'The Best Egg Nogg Recipe for the Holidays',
'Arrays with Style',
'PHP in the Enterprise',
'Douglas Crockford declares PHP his favorite language'
);
$diff = array_diff ( $index2, $index );
print_r ( $diff );
?>
Awesome. Our internet spider has found 3 new articles on the internet titled, ‘Arrays with
Style’, ‘PHP in the Enterprise’, and ‘Douglas Crockford declares PHP his favorite
language’. By passing our updated index and original index to the array_diff()function, it
returned only the new results to us.
Array
(
[6] => Arrays with Style
[7] => PHP in the Enterprise
[8] => Douglas Crockford declares PHP his favorite language
)
15. array_search
My buddy was telling me about a cool article named ‘PHP in the Enterprise’, I wonder if our
updated index was able to capture it yet? Let’s find out with array_search();
<?php
$index2 = array (
'How to Eat Apples',
'Surfing Safely in a Wave Pool',
'The Best Foods For Breakfast',
'How to Eat Apples',
'25 tips to blogging nirvana',
'The Best Egg Nogg Recipe for the Holidays',
'Arrays with Style',
'PHP in the Enterprise',
'Douglas Crockford declares PHP his favorite language'
);
$found = array_search ( 'PHP in the Enterprise', $index2 ); // (needle,haystack)
print_r ( $found ); // 7
?>
Well isn’t that cool? We see that it is in fact in the index at position 7, as returned
from array_search()
Learn more about array_search() at http://us3.php.net/manual/en/function.array-
search.php
16. array_reverse
When you want to turn an array upside down or rightside up, you can use
the array_reverse() function. I have added some elements to our original $array so we
can get a better feel for how array_reverse() treats the array with both associative and
indexed properties.
<?php
$array = array (
'websites' => array (
'Search' => 'Google',
'Social' => 'Facebook',
'News' => 'NY Times'
),
'friends' => array (
'Chris',
'Jim',
'Lynn',
'Jeff',
'Joanna'
),
16,
99,
13,
'newfriend' => 'Ken'
);
print_r ( $array );
print_r ( $array );
?>
And here we see the results of applying the array_reverse() to our $array
// before reverse
Array
(
[websites] => Array
(
[Search] => Google
[Social] => Facebook
[News] => NY Times
)
[0] => 16
[1] => 99
[2] => 13
[newfriend] => Ken
)
// after reverse
Array
(
[newfriend] => Ken
[0] => 13
[1] => 99
[2] => 16
[friends] => Array
(
[0] => Chris
[1] => Jim
[2] => Lynn
[3] => Jeff
[4] => Joanna
)
17. array_unshift
We have seen how easy it is to add items to the end of an array, but what if we need to
prepend something to our array? Well that is where our nifty little array_unshift()comes
in. Let’s see how it works by adding an interest of ‘music’ to our array:
<?php
$array = array (
'websites' => array (
'Search' => 'Google',
'Social' => 'Facebook',
'News' => 'NY Times'
),
'friends' => array (
'Chris',
'Jim',
'Lynn',
'Jeff',
'Joanna'
),
16,
99,
13,
'newfriend' => 'Ken'
);
print_r ( $array );
?>
Alrighty then! Check out that interest of music at the beginning of our array!
Array
(
[0] => music
[websites] => Array
(
[Search] => Google
[Social] => Facebook
[News] => NY Times
)
[1] => 16
[2] => 99
[3] => 13
[newfriend] => Ken
)
Maybe you’d rather prepend an associative keyed value rather than a numeric, in that case
you can simply add your original array to a key value pair like so:
<?php
$array = array ( 'interests' => 'music' ) + $array;
print_r ( $array );
?>
Array
(
[interests] => music
[websites] => Array
(
[Search] => Google
[Social] => Facebook
[News] => NY Times
)
[0] => 16
[1] => 99
[2] => 13
[newfriend] => Ken
)
Well there you have it friends, an epic journey through the most widely used PHP array
functions!
Now that we know exactly what Arrays in PHP are and how they work, what
does PHP the language offer us in terms of working with arrays? Surely we’ll
need to be able to count values in them, sort arrays by their contents, convert
them between strings and arrays, find unique values, search within arrays,
compare arrays to other arrays and more. PHP has got you covered with over
80, that’s right count them, functions to provide any type of operation you could
ever want to perform on an array. In this episode we’ll take a look at the very
most useful PHP array functions so that we can hit the ground running with
arrays. Let’s dig in!
• 1is_array()
• 2in_array()
• 3array_unique()
• 4array_search()
• 5array_reverse()
• 6array_map()
• 7array_diff()
• 8count()
• 9max()
• 10min()
• 11array_rand()
• 12array_count_values()
• 13sort()
• 14asort()
• 15rsort()
• 16arsort()
• 17implode()
• 18explode()
• 19array_key_exists()
• 20array_keys()
• 21array_values()
• 22array_push()
• 23array_pop()
• 24array_unshift()
• 25array_shift()
• 26array_splice()
• 27array_merge()
$dynamic = [
'number' => 7,
'live' => 'House',
'drive' => 'Car',
[
'mow' => 'grass',
[
'tractor' => 'John Deere',
'tractor2' => 'Kubota',
'tractor3' => 'New Holland'
],
'landscape' => 'mulch'
]
];
$one = is_array($dynamic);
$two = is_array($dynamic['number']);
$three = is_array($dynamic[0]);
echo $one ? 'The $dynamic variable is an array<br>' : 'The $dynamic variable is not an array<br>';
echo $two ? 'The "number" key of the $dynamic variable is an array<br>' : 'The "number" key of the
$dynamic variable is not an array<br>';
echo $three ? 'The 0 index of the $dynamic variable is an array<br>' : 'The 0 index of the $dynamic
variable is not an array<br>';
?>
if (in_array("Tomatoes", $veggies)) {
echo "The best Tomatoes make the best Red Sauce!<br>";
}
$dynamic = [
'number' => 7,
'live' => 'House',
'drive' => 'Car',
[
'mow' => 'grass',
[
'tractor' => 'John Deere',
'tractor2' => 'Kubota',
'tractor3' => 'New Holland'
],
'landscape' => 'mulch'
]
];
$tractor = $dynamic[0][0]['tractor'];
if (in_array('grass', $dynamic[0])) {
echo "Time to take a spin on the $tractor and get the grass cut!<br>";
}
?>
echo "The answers to all of your questions is located at index $index of the array."
?>
echo '<br>';
function lower($array)
{
return strtolower($array);
}
$arraytwo = [
'Google',
'Microsoft',
'Apple',
'Adobe',
'Cisco',
'Juniper',
'Lenovo',
'Samsung'
];
print_r($diff);
$tractor = $dynamic[0][0];
$tech = [
'Google',
'Microsoft',
'Apple',
'Adobe',
'Cisco',
'Juniper',
'Lenovo',
'Samsung',
'Red Hat'
];
$v1 = count($dynamic);
$v2 = count($veggies);
$v3 = count($tractor);
$v4 = count($tech);
echo "We have $v1 items in the dynamic array, $v2 vegetables, $v3 tractors, and $v4 tech companies.
Thanks for using the count function.";
$numbers = ['12', '234651', '234', '41', '89', '196583', '1', '86', '3', '5', '9'];
$rand = array_rand($numbers);
echo $rand;
<?php
$numbers = ['12', '234651', '234', '41', '89', '196583', '1', '86', '3', '5', '9'];
$rand = array_rand($numbers);
echo $rand;
234651
1
4
12. array_count_values( array $array )
This is an incredible array function you can make use of. What it does is take an array with
many values, and then counts the number of times each value occurs in the array. It does
this by turning the original array’s values into keys in the new array, and assigns a number
count for how many times that value occurred originally as the new value. An example is in
order. Say we had a huge array of stock ticker symbols. In this array there are tons of
entries that occur many many times. We’ll use this function to count how many times each
ticker is present.
<?php
$stocktickers = ['aapl', 'aapl', 'aapl', 'goog', 'goog', 'yhoo', 'fslr', 'msft', 'csco', 'csco'];
$values = array_count_values($stocktickers);
print_r($values);
?>
Array ( [aapl] => 3 [goog] => 2 [yhoo] => 1 [fslr] => 1 [msft] => 1 [csco] => 2 )
$tech = [
'Google',
'Microsoft',
'Apple',
'Adobe',
'Cisco',
'Juniper',
'Lenovo',
'Samsung',
'Red Hat'
];
$stocktickers = ['aapl', 'aapl', 'aapl', 'goog', 'goog', 'yhoo', 'fslr', 'msft', 'csco', 'csco'];
$numbers = ['12', '234651', '234', '41', '89', '196583', '1', '86', '3', '5', '9'];
echo '<pre>';
sort($mixed);
sort($veggies);
sort($stocktickers);
sort($numbers);
print_r($mixed);
print_r($veggies);
print_r($stocktickers);
print_r($numbers);
// sort($mixed);
Array
(
[0] => Car
[1] => House
[2] => 7
[3] => Array
(
[mow] => grass
[0] => Array
(
[tractor] => John Deere
[tractor2] => Kubota
[tractor3] => New Holland
)
)
// sort($veggies);
Array
(
[0] => Carrots
[1] => Corn
[2] => Cucumbers
[3] => Spinach
[4] => Tomatoes
)
// sort($stocktickers);
Array
(
[0] => aapl
[1] => aapl
[2] => aapl
[3] => csco
[4] => csco
[5] => fslr
[6] => goog
[7] => goog
[8] => msft
[9] => yhoo
)
// sort($numbers);
Array
(
[0] => 1
[1] => 3
[2] => 5
[3] => 9
[4] => 12
[5] => 41
[6] => 86
[7] => 89
[8] => 234
[9] => 196583
[10] => 234651
)
// asort($mixed);
Array
(
[drive] => Car
[live] => House
[number] => 7
[0] => Array
(
[mow] => grass
[0] => Array
(
[tractor] => John Deere
[tractor2] => Kubota
[tractor3] => New Holland
)
)
// asort($veggies);
Array
(
[2] => Carrots
[1] => Corn
[4] => Cucumbers
[0] => Spinach
[3] => Tomatoes
)
// asort($stocktickers);
Array
(
[0] => aapl
[2] => aapl
[1] => aapl
[8] => csco
[9] => csco
[6] => fslr
[4] => goog
[3] => goog
[7] => msft
[5] => yhoo
)
// asort($numbers);
Array
(
[6] => 1
[8] => 3
[9] => 5
[10] => 9
[0] => 12
[3] => 41
[7] => 86
[4] => 89
[2] => 234
[5] => 196583
[1] => 234651
)
// rsort($mixed);
Array
(
[0] => Array
(
[mow] => grass
[0] => Array
(
[tractor] => John Deere
[tractor2] => Kubota
[tractor3] => New Holland
)
[1] => 7
[2] => House
[3] => Car
)
// rsort($veggies);
Array
(
[0] => Tomatoes
[1] => Spinach
[2] => Cucumbers
[3] => Corn
[4] => Carrots
)
// rsort($stocktickers);
Array
(
[0] => yhoo
[1] => msft
[2] => goog
[3] => goog
[4] => fslr
[5] => csco
[6] => csco
[7] => aapl
[8] => aapl
[9] => aapl
)
// rsort($numbers);
Array
(
[0] => 234651
[1] => 196583
[2] => 234
[3] => 89
[4] => 86
[5] => 41
[6] => 12
[7] => 9
[8] => 5
[9] => 3
[10] => 1
)
// arsort($mixed);
Array
(
[0] => Array
(
[mow] => grass
[0] => Array
(
[tractor] => John Deere
[tractor2] => Kubota
[tractor3] => New Holland
)
[number] => 7
[live] => House
[drive] => Car
)
// arsort($veggies);
Array
(
[3] => Tomatoes
[0] => Spinach
[4] => Cucumbers
[1] => Corn
[2] => Carrots
)
// arsort($stocktickers);
Array
(
[5] => yhoo
[7] => msft
[3] => goog
[4] => goog
[6] => fslr
[9] => csco
[8] => csco
[1] => aapl
[0] => aapl
[2] => aapl
)
// arsort($numbers);
Array
(
[1] => 234651
[5] => 196583
[2] => 234
[4] => 89
[7] => 86
[3] => 41
[0] => 12
[10] => 9
[9] => 5
[8] => 3
[6] => 1
)
$glue = '*';
?>
Yaba*Daba*Doo*Who*Loves*You*?
<?php
$glue = '*';
print_r($array);
?>
Array
(
[0] => Yaba
[1] => Daba
[2] => Doo
[3] => Who
[4] => Loves
[5] => You
[6] => ?
)
$array = [
'phone' => 'iPhone',
'laptop' => 'Carbon X1',
'car' => 'Tesla',
];
if ($true) {
echo 'Why yes, yes I do in fact.';
} else {
echo 'No I use my tablet instead';
}
?>
$array = [
'phone' => 'iPhone',
'laptop' => 'Carbon X1',
'car' => 'Tesla',
];
$keys = array_keys($array);
print_r($keys);
?>
Array
(
[0] => phone
[1] => laptop
[2] => car
)
$array = [
'phone' => 'iPhone',
'laptop' => 'Carbon X1',
'car' => 'Tesla',
];
$values = array_values($array);
print_r($values);
?>
Array
(
[0] => iPhone
[1] => Carbon X1
[2] => Tesla
)
$array = [
'Apples',
'Blueberries',
'Pumpkins',
'Corn',
];
array_push($array, 'Watermelons');
echo '<pre>';
print_r($array);
?>
Array
(
[0] => Apples
[1] => Blueberries
[2] => Pumpkins
[3] => Corn
[4] => Watermelons
)
$array = [
'Apples',
'Blueberries',
'Pumpkins',
'Corn',
'Watermelons',
];
$yummy = array_pop($array);
?>
$array = [
'Apples',
'Blueberries',
'Pumpkins',
'Corn',
'Watermelons',
];
echo '<pre>';
print_r($array);
?>
Array
(
[0] => Apple Pies
[1] => Apples
[2] => Blueberries
[3] => Pumpkins
[4] => Corn
[5] => Watermelons
)
$array = [
'Apple Pies',
'Apples',
'Blueberries',
'Pumpkins',
'Corn',
'Watermelons',
];
$eat = array_shift($array);
?>
$array = [
'Apple Pies',
'Apples',
'Blueberries',
'Pumpkins',
'Corn',
'Watermelons',
];
array_splice($array, 3, 1, 'Chocolates');
print_r($array);
?>
Array
(
[0] => Apple Pies
[1] => Apples
[2] => Blueberries
[3] => Chocolates
[4] => Corn
[5] => Watermelons
)
$eats = [
'Apple Pies',
'Apples',
'Blueberries',
'Pumpkins',
'Corn',
'Watermelons',
];
$drinks = [
'Water',
'Apple Juice',
'Craft Beer',
'Iced Tea',
'Coffee',
];
echo '<pre>';
print_r($dinner);
?>
Array
(
[0] => Apple Pies
[1] => Apples
[2] => Blueberries
[3] => Pumpkins
[4] => Corn
[5] => Watermelons
[6] => Water
[7] => Apple Juice
[8] => Craft Beer
[9] => Iced Tea
[10] => Coffee
)
Well friends as they say in show biz, “That’s a WRAP!” We covered a ton of ground in this
episode of our Awesome PHP Tutorial Series. Hopefully you found some of the tips and
tricks useful and can apply them to your own projects.
Double Quotes
Double quotes are useful when you have a PHP variable you want to embed within the
string, since when the PHP runs, it will use interpolation to grab the actual value of that
variable.
<?php
$str = "Hi buddy, I'm a PHP String";
Single Quotes
Some people find it easier to leave their variables out of strings and let them be more hard
coded sort to speak. Use single quotes for that.
<?php
$str = 'Hi again, still a PHP String!';
Heredoc Syntax
<?php
$str = <<<EOD
Wordpress is really cool
HTML5 is the key to the open web
Who likes to use Twitter Bootstrap
We can have several lines here!
EOD;
Note: You don’t have to use EOD as your delimiter, you can use anything you like as long
as they are the same!
When you call the function with a positive number for start (only), you will get the string
from the start position to the end of the string.
<?php
$blog = 'Your Blog is Excellent!';
substr($blog, 1);
// returns 'our Blog is Excellent!'
substr($blog, 5, -13);
//returns 'Blog'
5 signifies the starting character point (B) and -13 determines the ending point (count 13
places backwards starting from the end of the string).
Learn more about substr() at http://us3.php.net/substr
2. strlen()
Next up we have the popular strlen() function for checking the length of a string. If you
pass it a string, strlen() will return its length.
<?php
echo strlen("Super Cali Fragilistics Expy Ali Docious");
// 40
Often times this function is used for validating input data or making sure a string variable
has a value.
<?php
$super = 'duper';
3. str_replace()
Find and replace functionality is super useful with strings. You can use find and replace for
almost anything your imagination can think of.
The most commonly used string function for replacement is str_replace(). It has the
following prototype:
mixed str_replace(mixed needle, mixed new_needle, mixed haystack[, int &count]));
str_replace() replaces all the instances of needle in haystack with new_needle and
returns the new version of the haystack.The optional fourth parameter contains the number
of replacements made.
A really awesome feature of str_replace() is the ability to pass an array to both the
search terms and replace terms, as well as an array of strings to apply the rules to!
<?php
$strings = array (
'You like to have a fun time',
'You are a really nice person',
'Would you like to have a cup of coffee?'
);
$search = array (
'fun',
'time',
'person',
'coffee'
);
$replace = array (
'excellent',
'adventure',
'individual',
'joe'
);
print_r ( $replaced );
/////////////////////////////////
Array
(
[0] => You like to have a excellent adventure
[1] => You are a really nice individual
[2] => Would you like to have a cup of joe?
)
?>
print_r ( $trimmed );
// awesome stuff
?>
5. strpos()
The function strpos() operates in a similar fashion to strstr(), except, instead of
returning a substring, it returns the numerical position of a needle within a haystack.
The strpos() function has the following prototype:
int strpos(string haystack, string needle, int [offset] );
The integer returned is the position of the first occurrence of the needle within the
haystack. The first character is in position 0 just like arrays.
We can see by running the following code that our exclamation point is at position 13.
<?php
$awesome = "Super Awesome!";
echo strpos($awesome, "!");
// 13
This function accepts a single character as the needle, but it can accept a string of any
length. The optional offset parameter determines the point within the haystack to start
searching.
<?php
$awesome = "Super Awesome!";
echo strpos($awesome, ‘m’, 3);
// 11
This code echoes the value 11 to the browser because PHP has started looking for the
character ‘m’ at position 3.
In any of these cases, if the needle is not in the string, strpos() will return false. To avoid
strange behavior you can use the === operator to test return values:
<?php
$awesome = "Super Awesome!";
// Not found
?>
6. strtolower()
Very often in PHP we need to compare strings or correct capitalization when people
SHOUT or do odd things. In order to compare strings, you want to make sure they are the
same case. We can use strtolower() for this purpose. We’ll use a function created
with strtolower() to calm down an angry person.
<?php
function calm_down($string) {
7. strtoupper()
strtoupper() is also quite popular for many of the reasons listed above, in reverse,
meaning take lowercase or a mixed case string and set it to all upper case. We’ll change
things up and create a wake up function to get our workers going in the morning.
<?php
function wake_up($string) {
8. is_string()
is_string() is used to check if a value is a string. Let’s take a look at this within an if()
statement to take an action on strings in one way and non-strings in
another. is_string() returns true or false.
<?php
if (is_string ( 7 )) {
echo "Yes";
} else {
echo "No";
}
// No
You pass strstr() a haystack to be searched and a needle to be found. If an exact match
of the needle is found, the strstr() function returns the haystack from the needle onward.
If it does not find the needle, it will return false. If the needle occurs more than once, the
returned string will begin from the first occurrence of the needle.
As an example, let’s say we have a submission form for people to submit their website, but
we would like it in a certain format. We can use strstr() to check for a string within a
string to help us here:
<?php
$url = 'vegibit.com';
echo $url;
// http://www.vegibit.com
?>
function function_name() {
// do stuff
}
The naming of the function is any string beginning with a letter or underscore followed by a
combination of digits, letters, or underscores. Make it easy on yourself and choose simple
descriptive naming for your functions, no need to get fancy. PHP functions are not case
sensitive however it is best practice to always use all lowercase letters. Though they don’t
have to, functions will usually return a value. This is done using the keyword return, and
any number of return statements can be used in the function in condition checking
scenarios. Once the return keyword is reached in the program, control goes back to the
calling code along with the value produced by the expression in the function. For example:
<?php
function br() {
echo '<br>';
// optional return statement
}
function add($num1, $num2) {
return $num1 + $num2;
// returning a value
}
Arguments to Functions
Functions can accept a certain number of arguments by declaring them in the function
definition. There are two different ways to pass parameters to a function and we’ll take a
look at them now.
Passing by value
Usually parameters are passed by value in PHP, but you also have the option of passing
by reference. The argument in the function is any valid expression which when evaluated
assigns the value to the variable in the function.
<?php
function doublefail($value) {
$value = $value * 2; // when this line runs $c retains 4
}
$c = 4;
doublefail($c);
echo $c; // 4
function doublefailreturn($value) {
return $value = $value * 2;
}
$d = 10;
echo doublefailreturn($d); // returns 20
echo $d; // leaves $d set to 10
?>
In the doublefail function, we use pass by value, so when the function runs, it doubles
the copy of the variable, not the value of the caller’s variable like the doubleitfunction
does. You could get what you want out of doublefail if you return the copy like in the last
example.
Passing by Reference
You can override the scoping rules and have the function gain direct access to a variable
by using pass by reference. To do this, you add an ampersand & to the front of the variable
name in the parameter list.
<?php
function doubleit(&$value) {
$value = $value * 2; // when this line runs $b gets set to 8
}
$b = 4;
doubleit($b);
echo $b; // 8
doubleit(7); // Fatal error: Only variables can be passed by reference
?>
The doubleit function passes $value by reference, that is to say the actual value
of $b instead of a copy of said value. This allows the function to modify the value directly
and when we then echo out the value, we see it gets doubled from 4 to 8 successfully.
Only variables can be supplied to parameters declared as passing by reference.
function awesomeFunction() {
// do awesome stuff
}
PHP gives you three functions to use in the function in order to get the parameters passed
to it.
func_get_args() returns an array of all parameters provided to a function;
func_num_args() returns the number of parameters provided to a function;
func_get_arg() returns a specific argument from the parameter list.
For example:
<?php
$array = func_get_args();
$count = func_num_args();
$value = func_get_arg(argument_index);
These functions cannot be directly used as a parameter to another function. You must first
set a variable to the result of the function, and then use that in the function call.
function returnIt() {
return 'It';
}
function returnArray() {
return array("Tom", 37, "Music");
}
or return an object:
<?php
class User {
public $userid;
public $name;
public $status;
}
function GetUser($userid) {
$userObj = new User();
$userObj->userid = $userid;
$userObj->name = 'Rick James';
$userObj->status = 'Super Freak';
return $userObj;
}
$newuser = GetUser(1);
var_dump($newuser);
?>
Recursive Functions
A recursive function is a function that calls itself. Recursion sounds straightforward, but
once you start working with it and try to really understand how it works, it can be very
tricky.
To write a recursive function, you need to provide it with some means of return or else it
will keep calling itself until the program crashes. This is known as the base case. The base
case is often found in a conditional like an if statement that will stop the recursion once a
condition is met. You also need a recursive case. This is where the recursion, or looping if
you will, takes place. The function is called on itself using the recursive case.
Factorials
The textbook example of recursion is the factorial example. The factorial function
symbol(!) means to multiply a series of descending non negative numbers like so:
4! = 4 × 3 × 2 × 1 = 24
7! = 7 × 6 × 5 × 4 × 3 × 2 × 1 = 5040
8! = 8 x 7 × 6 × 5 × 4 × 3 × 2 × 1 = 40320
Instead of manually doing this math, we could create a function that accepts a number,
and then calculates the factorial by recursion:
<?php
function factorial($number) {
if ($number < 2) {
return 1; // base case
} else {
return ($number * factorial($number-1)); // recursive case
}
}
factorial(4);
Many tutorials leave out the fact that this comes from the formula n! = n × (n-1)!which
means “the factorial of any number is that number times the factorial of (1 smaller than
that number)”
We’ll go step by step through this function using the number 4 to keep it manageable. To
do this I have put the code above into eclipse pdt and will step into each execution step.
1. The function definition gets read into memory
2. factorial(4); is called.
3. $number is now 4 so we move to the else clause
4. Recursion! The function calls itself passing in 3 as it’s parameter
5. $number is now 3 so we move to the else clause
6. Recursion! The function calls itself passing in 2 as it’s parameter
7. $number is now 2 so we move to the else clause
8. Recursion! The function calls itself passing in 1 as it’s parameter
9. $number is now 1 so we return 1
10. echo factorial(4); now outputs the answer of 24.
Variable Functions
Variable functions will be useful when we cover object oriented programming. In the mean
time we’ll look at the basics of how variable functions work. A variable function is simply
where you assign a function name to a variable and then you can call that function by
using the variable name.
Let’s remember our example of the factorial function. We could create a random variable
name and assign that function to it using the following syntax:
<?php
$fact = 'factorial';
//We can then call that function like so
echo $fact(5); //120
Note that language constructs such as echo() and isset() cannot be called through
variable functions:
<?php
$variable = "echo";
$variable("hello, world"); // does not work
Now that we have a good grip on functions in PHP, let’s whip up some PHP String Helper
Functions to help with common string manipulation tasks!
PHP is incredibly powerful right out of the box, even if you aren’t using any
frameworks. We need to be fluent with the language itself as well as the
frameworks we might like to use. Using the built in functions of the language we
can create our own functions, or wrapper functions, of the built in ones.
Sometimes this helps with just being able to more closely match your desired
workflow. In this example we are going to create some String Helper functions
to use that will help us to quickly work on strings in a very easy way. We’ll make
use of 6 built in PHP functions, those being, strtolower, strpos, substr, strlen,
preg_match_all, and str_replace, to build 4 new string helper functions. Let’s do
it!
Initial Configuration
Let’s first define some constants so that we can use these values in the helper functions.
<?php
split_string()
First up is the split_string() function. It allows us to break a string into two pieces based
on a setpoint, and then grab either side of the two pieces with or without the setpoint. It
uses the built in PHP functions strtolower, strpos, and substr.
<?php
find_between()
Next up is the find_between() helper function. This handy guy basically just makes use of
the split_string() function to help us to find a substring that is between a start and end
point that we give it.
<?php
// Finds a string between a given start and end point. You can include
// or exclude the start and end point
function find_between($string, $start, $stop, $incorexc) {
$temp = split_string ( $string, $start, AFTER, $incorexc );
return split_string ( $temp, $stop, BEFORE, $incorexc );
}
find_all()
Now we come to the find_all() function which is very useful. It makes use of the very
popular preg_match_all() function to find all occurrences of a pattern in between a starting
and ending delimiter. The real meat of this one is the pattern that gets passed
into preg_match_all(). We can see the first argument is the pattern consisting
of "($start(.*)$end)siU". This takes our start point, captures anything and everything
multiple times(.*), denoted by the dot and asterisk operators, stops at the end point,
performs a case insensitive match (i), excludes line breaks (s), and is not greedy (U).
These modifiers are extremely important for the RegEx to work properly.
<?php
delete()
The delete() function is useful for removing one, or many substrings from within a string.
We simply pass it a string, a start point, and an end point, and the function will take care of
the rest for us!
<?php
return $string;
}
// Finds a string between a given start and end point. You can include
// or exclude the start and end point
function find_between($string, $start, $stop, $incorexc) {
$temp = split_string ( $string, $start, AFTER, $incorexc );
return split_string ( $temp, $stop, BEFORE, $incorexc );
}
return $string;
}
Now when we want to use any of these functions we can simply include this file like so:
<?php
include('Stringhelpers.php');
and we will have access to our new functions! Let’s test it out. We’ll create a new file
called stringtest.php, include our helper file, and just call each new function on a small
piece of text. Let’s see the results:
<?php
include('Stringhelpers.php');
$string = 'Why do silly, green, or yellow frogs jump? Why do silly, green, or yellow frogs jump?';
Wow! That was really cool! Now what’s the big deal with all this Laravel we’ve been talking
about, then shifting gears and creating some simple PHP string helper functions?! Listen
now Grasshopper, there is a method to our madness! You see before frameworks, this is
how we did things. We created functions, we put them in files, we included those files into
other files, and tada!, WordPress was born. Just kidding – but in all seriousness, we all
probably have a lot of great functions and snippets of code in our arsenal. Once we start
using a great framework like Laravel, do we have to abandon those old functions that
we’ve come to know and love? But of course not! Now that we have created a file
containing a handful of helper functions, we will have something to work with for our next
tutorial. In our next episode, we’ll take a look at how to convert our old file based functions,
and put them into a dedicated class which can be added to a libraries folder in Laravel.
Then we’ll set up autoloading of any libraries we want to add to our project, and we’ll be
able to use the new hotness of Laravel, along with any of our own Library functions we’ve
collected over the years!
When we program, we need to find a balance between procedure and abstraction. The
function is the very beginnings of abstraction. When first setting out to solve a problem, we
may not even know how we are going to complete the task. At this early stage, it makes
sense to attack the problem with carefully planned steps or procedures. Once we have a
workable solution in place, we can put those procedures into a block of code, and create a
function with it. A function is this named block of code. It should perform a specific job,
and may accept parameters, also called arguments, given to it to perform it’s task. The
function will usually return a value. Functions make our code more efficient, and also
provide the benefit of saving on compile time. The reason being is that even if we call our
function 10 times within a page, it is compiled only once. Another benefit is that, if you
need to fix a bug or change logic within it, once it is updated in this one place, all other
function calls on this function, whether it be 10 or 100 other instances, will now work
correctly. It’s better to update code in one spot versus 100! Lastly, functions help make our
code more readable, especially if we give them meaningful names, and isolate their job to
a specific task.
We’ll take a close look at the syntax of defining functions, as well as the syntax of calling
both built in, and user defined functions.
Call a Function in PHP
No matter if a function was created by you, the awesome programmer, or if the function is
already a built in to the language, it will be evaluated in the same way.
$returnvalue = $named_function( [ parameter, ... ] );
A function might accept no parameters at all, or several parameters. Each function is
different. The parameters given to the function must be in a specific order, and can be any
valid expression, so long as it meets the expectations of the function definition. Passing in
parameters that are out of order can result in anything from unexpected results, to a full
fledged program crash. By reading the documentation of a function, you will know what it
expects.
Examples of Functions
array_unique()
array_unique() is a built in function that removes duplicate entries in an array
<?php
var_dump($unique);
array (size=3)
0 => string 'php' (length=3)
2 => string 'javascript' (length=10)
4 => string 'ruby' (length=4)
substr()
substr() is a built in function that allows you to find a substring within a string.
<?php
$gaming = substr("Playstation ".strlen('four')." is incredibly awesome!", 4, -1);
var_dump($gaming);
string 'station 4 is incredibly awesome' (length=31)
array_unshift()
array_unshift() is a built in function that allows you to add a value to the very beginning
of an array.
<?php
$legocharacters = array( 'Emmet', 'Vitruvius', 'Ma Cop', 'Pa Cop', 'Lord Business', 'El Macho');
array_unshift( $legocharacters, 'Biznis Kitty' );
var_dump($legocharacters);
array (size=7)
0 => string 'Biznis Kitty' (length=12)
1 => string 'Emmet' (length=5)
2 => string 'Vitruvius' (length=9)
3 => string 'Ma Cop' (length=6)
4 => string 'Pa Cop' (length=6)
5 => string 'Lord Business' (length=13)
6 => string 'El Macho' (length=8)
We call a function by simply referencing it’s name. In the first example, an argument is
passed to the function array_unique(). This argument is an array, because that is what
the function expects to be given. We can see that the array_unique() function accepts an
array, removes any duplicates from it, and returns the unique array.
The second example also accepts an argument, but in this case it is of type string. You
can see in this example how we can call a function within a function. In this
example, strlen() is called within substr(). The returned value of the inner function gets
passed to the outter function and then the final result is returned.
Lastly, we make use of the array_unshift() function which takes two parameters, an
array, and a value to add to the array.
PHP has a lot of built in functions. Were talking on the order of 5000+ built in functions
available for your enjoyment. When starting out, it may be difficult to know where to start.
One thing that may help is to determine the most used functions in the language and start
there. Since strings and arrays are the most common data types used, it makes sense to
start with the most popular php string functions and the most popular array
functions. Memorizing this small collection is enough to get you up and running for some
basic programming, and help you to debug your various themes and plugins.
$legocharacters = array( 'Emmet', 'Vitruvius', 'Ma Cop', 'Pa Cop', 'Lord Business', 'El Macho');
dump($legocharacters);
array (size=6)
0 => string 'Emmet' (length=5)
1 => string 'Vitruvius' (length=9)
2 => string 'Ma Cop' (length=6)
3 => string 'Pa Cop' (length=6)
4 => string 'Lord Business' (length=13)
5 => string 'El Macho' (length=8)
Let’s go over what is happening here. First we use the keyword function, this tell us that
the next piece of text is going to be the way we identify or name this block of code for
reuse. Second, we can see that the function expects a $value parameter to be passed in.
Note that you can assign any name you like to this parameter, it is simply an identifier for
what will be passed into the function when it get’s called. In this function, it is not optional,
we need this value passed in so the function will run without error. If we try to call
the dump() function with no parameters passed in, we will get a scary message that looks
like this:
Warning: Missing argument 1 for dump()
We can make a parameter optional by assigning it a value in the function declaration. Let’s
see what that would look like:
<?php
Now, when we call the dump() function without passing in any arguments, it will not bark at
us! When the function is called, it will see that no argument was given, therefore it will
assign the provided text from the function declaration to $value, and use that inside the
function. On the other hand, if we call the dump() function and pass in a value, the function
will ignore the text of the function declaration, and work it’s magic on the value that we
pass in, just like when we passed an array of $legocharacters to it. By providing default
values to your parameters in the function declaration, you are making your functions
more flexible and useful.
Returning a Value
The example above did not return a value, but normally a function would. When we want to
return a value from a function, we will use the return keyword. The return statement goes
inside the code block of the function. In fact, you can have many return statements inside
the function, since you may have some logic or tests that will run, and a value will be
returned only when a specific case occurs. Once a return statement is hit during the
programs execution, control gets handed back to the calling statement along with the
return value. The return keyword can accept any expression, it is quite flexible. You
can return $a + $b ( 5 / $c ); just as easily as return $a;. As an example we could
have an add function set up like this:
<?php
$teachers = array(
array('name' => 'Jen', 'job' => 'teacher', 'grade' => 5),
array('name' => 'Sarah', 'job' => 'teacher', 'grade' => 3),
array('name' => 'Heather', 'job' => 'teacher', 'grade' => 6),
array('name' => 'Lynn', 'job' => 'teacher', 'grade' => 5)
);
foreach($arr as $item){
$newarray[] = $item[$topluck];
}
return $newarray;
}
An array pluck function is very useful in many instances of web development. You may be
familiar with the MVC or Model View Controller pattern. When we use MVC and pass data
from controllers to views, usually the keys of the data array end up becoming the variable
names in the view. This is using the array pluck pattern to make this possible.
We can refactor the first iteration of our array_pluck() function using the built
in array_map() function. This will also help us see the return statement in a different light,
as well as highlight variable scope in php functions.
<?php
function array_pluck($topluck, $arr){
return array_map(function($item) use($topluck) {
return $item[$topluck];
}, $arr);
}
Array ( [0] => Jen [1] => Sarah [2] => Heather [3] => Lynn )
Awesome! As we can see this second iteration works just as well. Note that the return
statement is returning a complex expression in this example like we mentioned earlier.
Now wait a minute, what is that use($topluck) business all about? Well in PHP, a function
uses local scope, also called function level scope. This means that functions keep their
own sets of variables that are distinct from any others on the page and also of any other
functions. Variables in one function do not have access to variables in another function
and vice versa. The variables defined inside a function, including its parameter list, are not
available outside the function, and, by default, variables defined outside a function are not
accessible inside the function. How do we get around this?
function double($value) {
$value = $value * 2;
}
$number = 4;
double($number);
echo $number; // 4
This code is using pass by value, which means a copy of the variable is passed in.
Therefore when the function runs, it doubles the copy of the variable, not the value of the
caller’s variable. Fear not! We can fix this
Pass by Reference
We are going to do something drastic. We will entirely rewrite the function and use pass by
reference now:
<?php
function double(&$value) {
$value = $value * 2;
}
$number = 4;
double($number);
echo $number; // 8
?>
Yes it is working, and you’ll notice all we did was add the & operator to
Hey, it’s working now!
the parameter in the function declaration. This works because a copy is never made in
this case, the variable simply gets passed in. You can almost think of it like a pointer to a
memory address. Note that only variables can be supplied to parameters declared as
passing by reference. In addition, there is no reference sign on a function call – only on the
function definition. Function definitions alone are enough to correctly pass the argument by
reference.
Conclusion
We covered a lot in this PHP function tutorial. If you’re in the beginning stages of your PHP
journey, read this post many times until the concepts are second nature to you. If you’re
already an advanced code slinger, hopefully you found some nice refreshers in this post as
well. What’s next? Consider jumping into Object Oriented PHP!
file_exists()
bool file_exists(string path)
Returns true if the file at path exists and false if not.
file_exists() is used to check if a file, wait for it, exists!
If you want to see if a file exists without actually opening it, you can use file_exists()like
so:
<?php
if (file_exists("jobsinqueue.txt")) {
echo 'There are jobs in the queue waiting to be processed.';
} else {
echo 'There are currently no jobs in the queue.';
}
is_file()
bool is_file(string path)
is_file returns true if path exists and is a file, otherwise it returns false.
<?php
var_dump(is_file('atextfile.txt')); // true
var_dump(is_file('/app/blog/')); // false
is_readable()
bool is_readable(string path)
is_readable returns true if path exists and is readable, otherwise it returns false.
<?php
$filename = 'thefile.txt';
if (is_readable($filename)) {
echo 'The file is readable!';
} else {
echo 'The file is not readable';
}
is_writable()
bool is_writable(string path)
is_writable returns true if path exists and is a directory, otherwise it returns false.
<?php
$filename = 'writetome.txt';
if (is_writable($filename)) {
echo 'We can write to the file!';
} else {
echo 'Sorry, this file is not writable.';
}
filesize()
int filesize(string path)
You can check the size of a file by using the filesize() function. filesize returns the size
of a file in bytes and can be used in conjunction with fread() to read a whole file (or just a
part of the file) at a time. If the file does not exist or any other error occurs, the function
returns false.
fopen()
resource fopen(string path, string mode[, bool include [, resource context ]] )
fopen opens the file specified by path and returns a file resource handle to the open file. If
path begins with http://, an HTTP connection is opened and a file pointer to the start of
the response is returned. If path begins with ftp://, an FTP connection is opened and a
file pointer to the start of the file is returned; the remote server must support passive FTP.
If path is php://stdin, php://stdout, or php://stderr, a file pointer to the appropriate
stream is returned. Be aware of the different options with fopen()
ModeName Meaning
r Read Open the file for reading, beginning from the start of the file.
r+ Read Open the file for reading and writing, beginning from the start of the file.
Open the file for writing, beginning from the start of the file. If the file already exists, delete the existing
w Write
contents. If it does not exist, try to create it.
Open the file for writing and reading, beginning from the start of the file. If the file already exists, delete the
w+ Write
existing contents. If it does not exist, try to create it.
Cautious Open the file for writing, beginning from the start of the file. If the file already exists, it will not be
x
write opened, fopen() will return false, and PHP will generate a warning.
Cautious Open the file for writing and reading, beginning from the start of the file. If the file already exists, it will not be
x+
write opened, fopen() will return false, and PHP will generate a warning.
Open the file for appending (writing) only, starting from the end of the existing contents, if any. If it does not
a Append
exist, try to create it.
Open the file for appending (writing) and reading, starting from the end of the existing contents, if any. If it does
a+ Append
not exist, try to create it.
Used in conjunction with one of the other modes.You might want to use this mode if your file system
b Binary differentiates between binary and text files.Windows systems differentiate; Unix systems do not.The PHP
developers recommend you always use this option for maximum portability. It is the default mode.
Used in conjunction with one of the other modes.This mode is an option only in Windows systems. It is not
t Text
recommended except before you have ported your code to work with the b option.
ftell()
int ftell(resource handle)
ftell returns how far into the file the pointer is in bytes. If an error occurs, it returns false.
<?php
// where are we ?
echo ftell($fp); // 1
fclose($fp);
fclose()
bool fclose(int handle)
After you’ve finished using a file, you should close it as a best practice with fclose. You
should do this by using the fclose() function as follows:
<?php
fclose($fp);
This function returns true if the file was successfully closed or false if it was not.
$filename = "text.txt";
$handle = fopen($filename, "r");
$contents = fread($handle, filesize($filename));
fclose($handle);
file_get_contents()
string file_get_contents ( string $filename [, bool $use_include_path = false [,
resource $context [, int $offset = -1 [, int $maxlen ]]]] )
file_get_contents is an incredibly powerful function, file_get_contents() reads the file at
path and returns its contents as a string, optionally starting at offset. If include is specified
and is true, the include path is searched for the file. The length of the returned string can
also be controlled with the maxlen parameter.
<?php
$contents = file_get_contents('text.txt');
echo $contents; // Some awesome text!
file_put_contents()
int file_put_contents ( string $filename , mixed $data [, int $flags = 0 [,
resource $context ]] )
A close cousin of the file_get_contents() function and an alternative to fwrite() is
the file_put_contents() function. file_put_contents makes your life easy and writes the
string contained in data to the file named in filename without any need for
an fopen() (or fclose()) function call! Returns the number of bytes written to the file, or −1
on error. The flags argument is a bitfield with two possible values:
FILE_USE_INCLUDE_PATH If specified, the include path is searched for the file and the
file is written at the first location where the file already exists.
FILE_APPEND If specified and if the file specified by path already exists, string is
appended to the existing contents of the file.
LOCK_EX Exclusively lock the file before writing to it. Useful for preventing race conditions
during file writing.
<?php
file()
array file(string filename[, int flags [, resource context ]])
This handy function works a lot like readfile() except that instead of echoing the file to
standard output, it turns it into an array. Each key of the array contains one line of the file.
Flags can be one or more of the following constants when using the file function:
FILE_USE_INCLUDE_PATH Search for the file in the include path as set in the php.ini
file.
FILE_IGNORE_NEW_LINES Do not add a newline at the end of the array elements.
FILE_SKIP_EMPTY_LINES Skip any empty lines.
We have modified our text.txt file for an example and placed several lines of text on new
lines. Now you can see how the file() function reads the text in, and assembles an array:
<?php
$contents = file('text.txt');
print_r($contents);
Array
(
[0] => The most awesome text yet!
foreach(glob("/tmp/images/*.jpg") as $filename) {
// do something with $filename
}
basename()
string basename ( string $path [, string $suffix ] )
The basename() function gets the name of the file without the directory.
For example we could use basename like this:
<?php
$path = "/usr/local/httpd/index.html";
echo(basename($path)); // index.html
echo(basename($path, '.html')); // index
dirname()
string dirname ( string $path )
The dirname() function gets the directory name without the filename. dirname includes
everything up to the filename portion and doesn’t include the trailing path separator.
<?php
pathinfo()
mixed pathinfo ( string $path [, int $options = PATHINFO_DIRNAME |
PATHINFO_BASENAME | PATHINFO_EXTENSION | PATHINFO_FILENAME ] )
pathinfo returns an associative array containing information about path. If the options
parameter is given, it specifies a particular element to be
returned. PATHINFO_DIRNAME, PATHINFO_BASENAME, PATHINFO_EXTENSION,
and PATHINFO_FILENAME are valid options values.
<?php
$array = pathinfo('krumo/krumo.js');
print_r($array);
Array
(
[dirname] => krumo
[basename] => krumo.js
[extension] => js
[filename] => krumo
)
realpath()
string realpath ( string $path )
realpath expands all symbolic links, resolves references to /./ and /../, removes
extra / characters in path, and returns the result.
<?php
$string = realpath('krumo/krumo.js');
echo $string; // C:wampwwwphpconsolekrumokrumo.js
unlink()
bool unlink ( string $filename [, resource $context ] )
unlink deletes the file path, using the streams context context if provided. Returns true if
the operation was successful and false if not. This situation typically occurs if the
permissions on the file are insufficient or if the file does not exist.
<?php
unlink('text.txt');
rename()
bool rename(string old, string new[, resource context]))
The rename() function does double duty as a function to move files from place to place
since PHP does not include a move function. Whether you can move files from file system
to file system and whether files are overwritten when rename is used will likely depend on
your server environment, so be sure to check the effects on your server.
<?php
rename('newtext.txt', 'krumo/inKrumoDirectoryNow.txt');
// newtext.txt is now moved and renamed in one shot
// newtext.txt no longer exists in the original directory!
copy()
int copy(string path, string destination[, resource context ])
copy copies the file at path to destination. If the operation succeeds, the function
returns true, otherwise it returns false. If the file at the destination exists, it will be
replaced. The optional context parameter can make use of a valid context resource
created with the stream_context_create() function.
<?php
copy('krumo/inKrumoDirectoryNow.txt', 'copied.txt');
// copied.txt is now in the destination directory
// inKrumoDirectoryNow.txt still exists in the source directory
filemtime()
int filemtime(string path)
filemtime returns the last-modified time, as a Unix timestamp value, for the file path.
<?php
$modified = filemtime('copied.txt');
is_dir()
bool is_dir(string path)
is_dir returns true if path exists and is a directory, otherwise it returns false.
mkdir()
bool mkdir(string path[, int mode [, bool recursive [, resource context ]]])
mkdir creates the directory path with mode permissions. The mode is expected to be an
octal number such as 0755. An integer value such as 755 or a string value such as “u+x”
will not work as expected. Returns true if the operation was successful and false if not. If
recursive is used, it allows for the creation of nested directories.
opendir()
resource opendir(string path[, resource context])
opendir opens the directory path and returns a directory handle for the path that is
suitable for use in subsequent readdir(), rewinddir(), and closedir() calls. If path is not
a valid directory, if permissions do not allow the PHP process to read the directory, or if
any other error occurs, false is returned. Its use is similar to the use of fopen() for reading
from files. Instead of passing it a filename, you should pass it a directory name. The
function returns a directory handle, again in much the same way as fopen() returns a file
handle. When the directory is open, you can read a filename from it by
calling readdir($dir), as shown in the example. This function returns falsewhen there are
no more files to be read. Note that it will also return false if it reads a file called 0; in order
to guard against this, we can explicitly test to make sure the return value is not equal
to false:
<?php
$dir = opendir($current_dir);
while(false !== ($file = readdir($dir))) {
// do stuff
}
When you are finished reading from a directory, you call closedir($dir) to finish. This is
again similar to calling fclose() for a file.
readdir()
string readdir([resource handle])
readdir returns the name of the next file in the directory referenced by handle. If not
specified, handle defaults to the last directory handle resource returned by opendir(). The
order in which files in a directory are returned by calls to readdir() is undefined. If there
are no more files in the directory to return, readdir() returns false.
chmod()
bool chmod(string path, int mode)
chmod attempts to change the permissions of path to mode. The mode is expected to be
an octal number, such as 0755. An integer value such as 755 or a string value such as
“u+x” will not work as expected. Returns true if the operation was successful and false if
not.
Awesome! Now you can easily make use of this class like so:
<?php
include('fileclass.php');
File::put('newfile.txt', 'The first file created with our file class!'); // create a new file
echo File::size('newfile.txt'); // 43
File::read('newfile.txt'); // The first file created with our file class! NEW DATA!
File::clear('newfile.txt');
Conclusion
This was a fantastic crash course on the most popular file functions used in PHP. Learning
and memorizing the functions in this tutorial will take us a long way in sharpening our
programming chops.
Class:
It all starts with the class. The class is the master plan, dare I say the cliche but true,
blueprint, for your code. I like master plan though, it sounds a little more grand. In basic
terms, the class is a template or outline for creating objects.
Object:
The object comes from the class, much like a house would be built using a blueprint. We
call an object an instance of the class. One class can have many instances. Let’s say we
have a Person Class. As you know, we can have many people. At last count, I think there
are about 7 with a B, Billion of us on the planet. That’s a lot of objects coming from the
master class
Properties:
Objects have variables to store and manipulate data, but in OOP, they are
called properties.
Methods:
Just as we have variables, we also have functions, but again in OOP, they go by a
different name, method.
Encapsulation:
Our methods and properties in the class have visibility. You have likely seen
the public, private, and protected keywords. When you see these, you know that the
code is implementing encapsulation, or determining what can, or can not be, accessed
from inside and outside the class. The key points to know are:
Inheritance:
Inheritance is what we love about object oriented php. Inheritance is where we are able to
have very powerful code reuse. A new class can extend the parent class and even add or
modify existing properties and methods. It’s like a child that inherits all of her parent’s
greatness, and adds her own as well! The original class gets named things like base
class, parent class, or superclass. The new class is called the subclass or derived
class.
Using inheritance makes it possible to build on existing generic classes. Using a general
base class, one could create more focused and complex child classes as the need
becomes apparent. By following this convention, frequent and repeating blocks of code
can be written once in the superclass, instead of over and over in different subclasses. It
may also help to better resemble real world relationships. A simple test to see if
inheritance could or should be used is to insert an “is a” between the classes. If it makes
sense, then you could likely use inheritance. For example the sentence, “A Teacher is a
Person”, makes sense. It could make sense for a Teacher subclass to inherit from a
Person superclass. Not all Persons are Teachers however, so a Person would not inherit
from a Teacher.
Instantiating an Object
It’s easy to create a new object to use in our PHP program. We make use of
the newkeyword following this format:
<?php
Depending on how the class was defined, we might be able to pass arguments during the
creation of an object. Let’s assume we can in this example so we can pass arguments like
so:
<?php
This would create a new car object and store it in $car. We can now access the methods
and properties of the object using the arrow operator. The official name
is T_OBJECT_OPERATOR, however arrow operator is easier to remember since it looks
like an arrow ->!
We can also pass an argument to a method call. The method can also return a value just
like normal php functions:
<?php
$car->accelerate(75); // go 75 mph
As we mentioned in the terms section above, encapsulation allows us to set the methods
and properties to either public, private, or protected in the class definition. In addition to
this normal process of object creation, we can use what are called static methods and
properties. When you do this, the method is called on the class itself, not the created
object. Statics are somewhat frowned upon in the community, but they are great for quick
and dirty problem solving, and their syntax is very elegant. The example from our File
Class is very easy to read and use:
<?php
You may not want to build a whole application out of static methods and properties, but for
helper type classes, they make a great option.
Passed by Reference
Objects are passed by reference in PHP. This saves memory in the computer and
provides the ability to maintain state of the object. For example:
<?php
$c = $car;
$car->setMake('Porche');
var_dump($c);
object(Car)[1]
public 'make' => string 'Porche' (length=6)
public 'year' => int 2017
Wow! Even though we called the setMake() method on the $car object, a var_dump
of $c shows that the make is changed to ‘Porche‘! This is because both $c and $car point
at the same object
To make a true copy you can use the __clone() method like so:
<?php
$c = clone $car;
$car->setMake('Porche');
var_dump($c);
object(Car)[2]
public 'make' => string 'Subaru' (length=6)
public 'year' => int 2017
CoolNow we can see that a copy has been made and $car will contain Porche while $c will
contain Subaru!
Defining A Class
Using classes that have been created for us is quite easy. We simply use
the new keyword, instantiate some objects, and then we can enjoy all the methods and
properties that the developers created for us. A great example of this is when we create a
new object in one of the many great php frameworks. Defining our own classes is a little
more tricky! When we define a class, we determine a class name, class properties, and
class methods. Class names are case insensitive, though it’s best practice to capitalize
your class names. At a minimum we can declare a class like so:
<?php
class Classname {
If we include all available options to us when creating our classes, the syntax would look
like so.
class classname [ extends baseclass ] [ implements interfacename , [interfacename, ... ] ]
{
[ use traitname, [ traitname, ... ]; ]
[ visibility $property [ = value ]; ... ]
[ function functionname (args) {
// code
}
...
]
}
class Car {
public $make;
public $year;
This shows how the setMake() method makes use of $this to access and set
the $make property of the current object. We can also declare a static method using
the static keyword, just remember when calling that method, you call it on the class, not
the object. Recall from our php file functions tutorial:
<?php
class File {
public static function put($file, $data, $append = false) {
if ( $append ) {
return file_put_contents($file, $data, FILE_APPEND | LOCK_EX);
}
return file_put_contents($file, $data, LOCK_EX);
}
}
Note that we use the Scope Resolution Operator, or double colon, instead of the arrow
operator, which allows access to static, constant, and overridden methods or properties in
a class. The official name for the double colon operator is, get this, the Paamayim
Nekudotayim, for which I have no idea how to pronounce
We can lock down our methods by using the final keyword. This stops classes that
extend the parent class from overriding the method.
For example:
<?php
class Car
{
public $make;
final function getMake()
{
return $this->make;
}
}
Setting the visibility of a method is easy by using any of the keywords public, private,
or protected. If you do not specify a visibility, the method will default to public. For
example if we set $make to private, we’ll now get a fatal error if we try to access it outside
of the class:
<?php
class Car {
private $make;
public $year;
function __construct($make, $year){
$this->make = $make;
$this->year = $year;
}
$car->setMake('Porche');
We could however still set the private property and get access to the private property since
the methods we use to access it setMake() and getMake(), are public.
Pretty Cool!
Defining Properties
We’ve been defining properties all along in the examples so far. No doubt you’re used to
working with variables in your programs, well properties work the same way except they
are tied to an instance of an object. In order to get access to them, we need to use the
object. Declaring properties are optional, but certainly a best practice since it makes our
code much more readable. For the lazy among us, we could rewrite the Car class without
explicit property declaration like so and we can still set and get the make property:
<?php
class Car
{
function getMake()
{
return $this->make;
}
function setMake($make)
{
$this->make = $make;
}
}
You can also set default values to properties on declaration so long as those default
values are simple constants:
<?php
As you know, we have the option of declaring our properties to public, private, or
protected, based on how much visibility we would like to assign to them. We can also set
them to static and interact with them like so:
<?php
class Car
{
static $color = 'Blue';
}
$color = Car::$color;
Inside the object class, you can get access to the static property using the self keyword,
like so self::$color.
Getters and Setters
A key advantages of OOP is that it encourages encapsulation. This can be enforced with
the use of __get and __set functions. They may seem a little mundane, but the way these
get and set functions work is really cool! This allows you to access the class properties via
those methods rather than directly. For example:
If, instead of accessing the attributes of a class directly, you write accessor functions, you
can make all your accesses through a single section of code. When you initially write your
accessor functions, they might look as follows:
<?php
class Car
{
private $make;
function __get($name)
{
return $this->$name;
}
Note!The __get() function simply returns the value of the property, while
the __set() function assigns a value to a property. __get() takes a single parameter,
and __set() uses two. These functions do not get called directly! They have special
meaning in PHP just like __construct() and __destruct(). When trying to set or get
properties by something like $car->make = 'Toyota'; or echo $car->make;, what happens
is under the hood, the __set() or __get() functions get magically called for you with the
parameters supplied! So what’s the benefit you ask? Well, you could write
the __set() function so that it filters or restricts what data can be assigned. Maybe we
don’t like Chevy cars. Well we can prevent our objects from becoming Chevys like so:
<?php
class Car
{
private $make;
function __get($name)
{
return $this->$name;
}
class Car
{
const WHEELS = 4;
const ENGINE = 1;
}
echo Car::WHEELS; // 4
Inheritance
When we want to inherit methods or properties from a class we must use
the extendskeyword. We could extend our Car class like so:
<?php
Cool! You’ll
note that that there are no property or method definitions whatsoever in
our Racecar class, yet we can still set and get the make of our new Racecar! That is
because Racecar has inherited everything from Car by way of the extends keyword.
Private and Protected
If you are not specifying otherwise, everything from the base class will get extended to the
child. You may want to limit what can be inherited though. In that case you could use
either private or public like so:
<?php
class Car
{
private $make = 'Nissan';
protected $topspeed = 125;
public $color = 'Green';
}
class Car
{
public $make = 'Nissan';
public $topspeed = 125;
public $color = 'Green';
function speed(){
return $this->getTopSpeed();
}
function color(){
return $this->getColor();
}
}
Interfaces
Interfaces are becoming more popular in use. The Laravel Framework and it’s community
is especially keen on their use. Interfaces are a contract that define what methods a class
must implement. Any class that implements the interface must provide implementations for
all methods in the interface. The benefits to using an interface are many, once an
application begins to grow in size. Testing, code maintenance, and swapping of
implementations are the main factors to consider. An example interface might look
something like this:
<?php
interface Raceable
{
function hitTheGas();
}
Note that the interface is merely a definition, it does not contain any actual code!
Constructors
No discussion of object oriented programming is complete without talking about
constructors. Constructors are very useful to us for setting default values and getting our
object ready for use right away. They also allow us to pass arguments to our objects as
they are created. Let’s rewrite our Car class using a constructor:
<?php
class Car
{
public $make;
public $topspeed;
public $color;
var_dump($car);
object(Car)[1]
public 'make' => string 'Honda' (length=5)
public 'topspeed' => int 110
public 'color' => string 'Red' (length=3)
This is great! We can see that as soon as the object is created, it’s key properties are set
right away. Let’s make one more $car object and pass in different parameters just to be
sure it works:
<?php
var_dump($car);
object(Car)[1]
public 'make' => string 'Kia' (length=3)
public 'topspeed' => int 120
public 'color' => string 'Gray' (length=4)
class Car
{
public $make;
public $topspeed;
public $color;
function __destruct(){
echo 'Turning the Car off now.';
}
}
Conclusion
Object Oriented PHP is a large topic and one blog post can not do it justice! This was
however, a great overview of the key terms, techniques, and ideas when beginning to
learn OOP in PHP. Since we like to talk about and implement many of the great PHP
frameworks, it is mandatory that we know how their object oriented core works under the
hood. I hope you found some good bits of information here whether you are a beginner or
even a more experienced programmer just brushing up on the fundamentals.
Framework Agnostic
We’ve been using composer with our Laravel projects and tutorials, but Composer is much
bigger than that. By using Composer you can plug in software packages into your favorite
PHP framework, whether that be Laravel, Codeigniter, Yii, Symfony, Zend, Slim, FuelPHP,
and more. The benefit here is that you do not become so much dependent on learning all
of the different nuances of a framework, only to have to start over if you need to work on a
different project that uses a different framework.
Install Composer
First up, we need to install Composer. We can do this easily on *nix or Windows systems.
*nix based
$ cd /var/www/mykillerapp
$ curl -s http://getcomposer.org/installer | php
To see all the commands available to run you can do the following
$ php composer.phar
Windows Based
For the lazy among us the like a one click installation,
click https://getcomposer.org/Composer-Setup.exe and run the program. The installer
downloads composer and configures the system so you can run composer from any
directory. In fact, in windows explorer, if you right click on various folders you’ll see options
like Composer Init, Composer Options, Self Update, Show Help, Run as Admin, and Use
Composer Here. Quite handy indeed!
Available Commands
Once Composer is installed you can run a slew of commands from the command line. Hit
the official docs for the exhaustive details, or check out this list here of the most commonly
used ones you might run into: install, update, require vendor-name/package-
name, init, create-project symfony/framework-standard-edition dir/, run-
script, search my keywords, validate, config --list, self-
update, status, diagnose, help, show, global, licenses, archive, depends vendor-
name/package-name, dump-autoload --optimize
Check out this awesome Composer Cheat Sheet for Developers for an explanation of each
command.
composer.json
The configuration file for Composer is your composer.json file. It contains everything to tell
Composer how to operate and consists of, you guessed it, json data! The data within
specifies settings and package requirements for a given application. A really
basic composer.json file would look like this:
{
"require": {
"lego/pieceofresistance": "*"
}
}
This will require the “pieceofresistance” package, created by “lego”, and will require any
version. More commonly, you might like to use a specific verison like this:
"lego/pieceofresistance": "2.0.3"
Often times you will see major versions specified and minor versions given the wildcard
like this:
"lego/pieceofresistance": "2.0.*"
Cool! You now have a package (fictional in this case) so you can run the installcommand.
This is when the magic starts happening. If you remember manually trying to find and
download different scripts to try out on your local server, rejoice! With this approach, the
files start downloading in the background and get placed into the vendors/ folder at the
root of the application. Better yet is to specify where you would like the files placed in
the composer.json like so:
{
"require": {
"lego/pieceofresistance": "2.0.*"
},
"config" : {
"vendor-dir" : "packages"
}
}
Let’s now actually use Composer to specify some packages to download. The first
example will be an really fantastic PHP Console that you can use for testing snippets of
PHP without having to actually create a PHP file, save it, load it, and so on. We’ll make
use of the seld/php-console package.
C:wampwwwphpcon>composer init
Welcome to the Composer config generator
This command will guide you through creating your composer.json config.
Package name (/) [vegibit/phpcon]: demo/forfun
Description []: just a test of composer
Author: fred
Minimum Stability []: dev
License []:
Define your dependencies.
Would you like to define your dependencies (require) interactively [yes]? no
Would you like to define your dev dependencies (require-dev) interactively [yes]? no
{
“name”: “demo/forfun”,
“description”: “just a test of composer”,
“authors”: [
{
“name”: “fred”,
“email”: “fred@flinstone.com”
}
],
“minimum-stability”: “dev”,
“require”: {
}
}
Do you confirm generation [yes]? y
C:wampwwwphpcon>
If we now look at the composer.json file created for us, it will appear as so:
{
"name": "demo/forfun",
"description": "just a test of composer",
"authors": [
{
"name": "fred",
"email": "fred@flinstone.com"
}
],
"minimum-stability": "dev",
"require": {
}
}
We didn’t specify any dependencies during the composer init command, so you’ll see that
the require object is empty. We can manually update it once we find something
from https://packagist.org/ that we would like to use. In this example we are going to
use https://packagist.org/packages/seld/php-console. We can now
update composer.json manually like so:
{
"name": "demo/forfun",
"description": "just a test of composer",
"authors": [
{
"name": "fred",
"email": "fred@flinstone.com"
}
],
"minimum-stability": "dev",
"require": {
"seld/php-console": "1.4.*"
}
}
Now pretend you didn’t do this manually, or simple delete any entries in the require object.
We can also complete the same task using composer require
C:wampwwwphpcon>composer require
Search for a package []: seld
Found 3 packages matching seld
[0] seld/jsonlint
[1] seld/php-console
[2] seld/slippy
Enter package # to add, or the complete package name if it is not listed []: 1
Enter the version constraint to require []: 1.4.0
Search for a package []:
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
– Installing seld/php-console (1.4.0)
Loading from cache
Writing lock file
Generating autoload files
C:wampwwwphpcon>
Excellent! This updates your composer.json file and pulls in the dependencies in one shot.
Note that there is also a new file in the directory called composer.lock. This is a *very*
important file! Basically what it does is lock in the versions you have specified in
the composer.json file so that if you or someone else runs composer install in the future,
only those specified versions will be installed, *not* the latest and greatest versions which
might cause bugs or breakage of your app.
You can bypass this by using composer update. What this command does is pretend that
a composer.lock file is not there, or just ignores it. Composer will look for any
wildcard * characters in the composer.json file and download the latest versions for the
dependencies. Maybe you want this, maybe you don’t. Just be aware of the difference
between composer install and composer update.
If you look in the project directory you’ll now notice a vendor directory in addition to
the composer.json and composer.lock files. If we open up the vendor directory, you’ll see
the composer folder and the seld folder dependency in addition to an autoload.php file.
Inside of the seld folder we have the package we were looking for, php-console. Now
check this out, let’s browse to http://localhost/phpcon/vendor/seld/php-console/ and
observe the result in all of it’s glory:
There you go. Your own PHP console sandbox to quickly test snippets of code with the
click of a button. No downloading all kinds of zip files, extracting them, copy and paste,
none of it. Just use composer, enter a few commands, and get yourself a nice piece of
software to test and use.
Lets add another requirement to this project.
C:wampwwwphpcon>composer require
Search for a package []: twitter/bootstrap
Found 15 packages matching twitter/bootstrap
[0] twitter/bootstrap
[1] libra/twitter-bootstrap-assets
[2] mwillbanks/zfc-twitter-bootstrap
[3] kvdh/symfony-twitter-bootstrap
[4] toa/twitter-bootstrap-bundle
[5] phpugl/twitter-bootstrap-bundle
[6] evheniy/twitter-bootstrap-bundle
[7] typo3/twitter-bootstrap
[8] jlong/sass-twitter-bootstrap
[9] kvdh/symfony-twitter-bootstrap-datetime-picker
[10] twitter/bootstrap-bundle
[11] ppi/twitter-bootstrap-module
[12] patricktalmadge/bootstrapper
[13] komola/bootstrap-zend-framework
[14] yiisoft/yii2-bootstrap
Enter package # to add, or the complete package name if it is not listed []: 0
Enter the version constraint to require []: dev-master
Search for a package []:
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
– Installing twitter/bootstrap (dev-master 541a75f)
Downloading: 100%
Writing lock file
Generating autoload files
C:wampwwwphpcon>
Again, this updates our composer.json and pulls in the dependency all at once, cool!
Using Composer is a great way to simplify workflow and manage dependencies in your
PHP projects, whether you’re working on UNIX, Linux, Mac, or Windows. Not only that,
Composer offers powerful autoloading features that we’ll tackle in our next episode. Try it
out today and see what you think.
1. In our web root, create a folder named aldemo, for auto load demo.
2. Now we can add a folder to hold our custom code. We can call it mylibrary
3. Add a functions.php file in there, and define a custom function for yourself. We’ll use
this one, but you can create your own if you like.
4. Now we can use Composer to generate the autoload files for us. Create
a composer.json file and place it in the aldemo folder like so:
5. Run composer dump in the aldemo folder. It will note that it is Generating autoload
files for you.
6. Create an index.php file in the aldemo folder and make a call to your new function.
We simply did this:
7. Now load up your page in the browser http://localhost/aldemo/ and see the result.
Ouch. That didn’t work out so well: Fatal error: Call to undefined function lego() in
C:wampwwwaldemoindex.php on line 3
8. We still need to include the autoloader like so! require 'vendor/autoload.php';.
Your index.php will now look like:
9. Once again go ahead and visit http://localhost/aldemo/ and observe that yes, You
are now a master builder.
Note that you need to use a Class! The classmap loads only Classes, whereas
with files, you can load native functions.
The naming might not have been the best for this example, but it will do. You’ll see
the new classmap object within the autoload object, and it now has an array with one
value, classmap. That says, “We are using a classmap, and I want you to look in the
classmap folder to autoload any classes you find.”
Now hold on just a minute! You have two different namespaces in the
same greeting.php class file. Not only that, each namespace has the exact same
class name and method name! Normally PHP would unleash a rath of fury and anger
upon you if you tried to do this without namespaces! This is the benefit of
namespaces however, you can have classes and methods that use the same name,
as long as they are in their own namespace. Excellent!
3. Let’s update our composer.json so that it has the needed info to load these classes
using PSR-0
Now check it out. What this configuration says is,
“The VegibitLibrary and VegithemesLibrary namespaces both live in
the src directory.
We changed psr-0 to psr-4, and added \ to the end of our namespaces which is a
requirement of psr-4.
So you see, using PSR-0, developers were forced to use lengthy directory structures
which created a lot of empty directories. This was only needed to make the autoloader
work. With PSR-4, we no longer have to use such verbose directory paths.
If you come from the C sharp or Java World, namespaces are not a new idea to
you. In PHP, it was only once PHP 5.3 was released that namespaces gained
official support in the language. Namespaces are changing the way applications
in PHP are written, and they are likely one of the most important additions to
the language in recent times. In this episode, we’ll take a look at what
namespaces are, why they benefit us, and how to use them. Let’s dig in!
Any PHP code that comes after this line now lives in the Vegibit namespace. You can also
define more than one namespace in the same PHP file like so:
<?php
namespace Google;
Class Search {
Class Search {
Truth be told, it’s probably a good idea to keep your namespace to one per PHP file. After
all, you’re using namespaces to reduce collisions and confusion in the application, no need
to complicate things. The above example does highlight nicely the benefit of namespaces
however. Notice that both the Google and Bing namespace each have a class named
search and a method named query? You can’t do that in the global namespace! Since we
declared these classes and methods in different namespaces however, we can use each
class and method to our hearts content, with no need to worry about running into
collisions.
function learning() {
return 'Get your learn on';
}
class Organization {
static function teamplayer() {
return 'There is no I in team';
}
}
Results in:
Infinity
Get your learn on
There is no I in team
You’ll note that we had to use the full namespace path in order for this code to run
successfully. This is what is referred to as a fully qualified namespace and includes the
initial backslash. So what happens if we just put this application code inside the same
namespace? Let’s see!
application.php (namespaced)
<?php
namespace Applicationvegilib;
require ('vegilib.php');
Infinity
Get your learn on
There is no I in team
Awesome! Since we now have the application code living in the same namespace, you can
see that instead of having to use the full path in our execution code, we can simply access
our constant, function, and class method directly since we are in the same namespace.
Importing Namespaces
As we just saw, you can place your application code into the same namespace as your
library, and this will give you direct access to the guts of that library without having to
specify the fully qualified namespace. Let’s look at importing namespaces using
the use and as keywords, it’s quite slick! We’ll break up our earlier example of the Google
and Bing namespaces into separate class files for this example.
google.php
<?php
namespace Google;
Class Search {
bing.php
<?php
namespace Bing;
Class Search {
require ('google.php');
require ('bing.php');
Results in
Searching Google
Searching Bing
We’ll now find that we can search Google and Bing using the same Class and Method
names, just from another namespace. Make note of both use Google as g; and use Bing
as b;. What this says is that we want to use each namespace as something else. So in the
case of the Google namespace, we can instantiate an object like this $searchengine = new
gSearch; and to instantiate an object in the Bing namespace we can do this $searchengine
= new bSearch;
If we omit the lines:
<?php
use Google as g;
use Bing as b;
we can still use those classes and methods but we’ll now have to include the full
namespace when trying to instantiate an object like this:
<?php
require ('google.php');
require ('bing.php');
Searching Google
Searching Bing
Some of this is a matter of preference, while some of this is quite nuanced to the point of if
you don’t follow the conventions very specifically, your app will break. When in doubt, hit
up the official docs and various definitions and rules to be sure you are following the best
practices.
What is __NAMESPACE__ ?
This is a constant that refers to the current namespace. In the global namespace, this
constant has no value, or an empty string. Let’s adjust our most recent application code to
test this out:
<?php
namespace Bing;
use Google as g;
require ('google.php');
require ('bing.php');
echo __NAMESPACE__;
Now what we have here is a snippet of PHP code that lives in the Bing namespace. Within
this namespace we import the Google namespace and alias it as the letter g. Therefore,
the object creation and method call runs, and we search google. Be echoing out the
__NAMESPACE__ constant, we can see that yes, this file does live in the Bing
namespace.
Searching Google
Bing
So what is this good for? A good question indeed! It turns out you can use this constant for
debugging purposes as well as to create dynamically generated fully qualified class
names.
Welcome to the Ultimate PHP String Functions List with 70 Must Know PHP
String Functions. You can find all kinds php string functions tutorial articles
online, however this php string functions cheat sheet will be the ultimate guide
to using string functions in php. We took an exhaustive approach in coming up
with the list and sorted the entire list based on frequency of use in the PHP
community, usefulness, and importance of learning with regard to your php
development. You can use this list to study for php string functions interview
questions, or just to brush up on your own skills for self improvement. However
you use the list is up to you. Now Let’s dig in to the ultimate list of php string
functions.
When you’re starting with PHP, it’s so easy to be overwhelmed by the sheer number of
functions available to you. In this episode we happen to be studying php strings. Now what
makes this list useful, maybe even more useful than just the list the documentation
provides, is that we ran a program over the top php repositories online today and found out
how many times each of these functions was used overall. This tells us what functions the
pros are using, so it makes sense to focus on the ones that are giving the most mileage to
them. That means the php string functions we have here, especially the ones near the top
of the list, are extremely useful and will be the ones that we first learn and commit to
memory.
• 1substr()
• 2strlen()
• 3sprintf()
• 4echo()
• 5strpos()
• 6implode()
• 7str_replace()
• 8strtolower()
• 9explode()
• 10chr()
• 11trim()
• 12str_repeat()
• 13strtoupper()
• 14str_pad()
• 15ord()
• 16strtok()
• 17strstr()
• 18rtrim()
• 19md5()
• 20strrpos()
• 21join()
• 22bin2hex()
• 23ltrim()
• 24substr_replace()
• 25str_split()
• 26sha1()
• 27ucfirst()
• 28chunk_split()
• 29ucwords()
• 30htmlspecialchars()
• 31stripos()
• 32substr_count()
• 33number_format()
• 34stripcslashes()
• 35strstr()
• 36wordwrap()
• 37addcslashes()
• 38parse_str()
• 39strcmp()
• 40strip_tags()
• 41substr_compare()
• 42setlocale()
• 43str_ireplace()
• 44strncasecmp()
• 45crypt()
• 46printf()
• 47quoted_printable_decode()
• 48sscanf()
• 49crc32()
• 50htmlentities()
• 51levenshtein()
• 52strcasecmp()
• 53strcspn()
• 54strripos()
• 55strspn()
• 56html_entity_decode()
• 57str_shuffle()
• 58stristr()
• 59strpbrk()
• 60strrev()
• 61addslashes()
• 62count_chars()
• 63md5_file()
• 64nl2br()
• 65sha1_file()
• 66str_word_count()
• 67strnatcasecmp()
• 68strnatcmp()
• 69strncmp()
• 70chop()
1. substr() definition: The substr() function returns a part of a string.
Usage:If you know where the information that you want lies in a larger string, you can
extract it out with the substr() function.
length Not Mandatory. Specifies the length of the returned string. Default is to the end of the string.
Code Example
<?php
$sentence = "The Apple iPhone 6 Plus is cool, just don't bend it";
$one = substr($sentence, 9, 10);
$two = substr($sentence, 24, 27);
2. strlen() definition: The strlen() function returns to us the number of characters in the
string it’s given.
There are many times when you will need to know the length of a string.
Usage:
The strlen() function makes this super easy for us.
strlen function signature strlen(string)
Argument Argument Meaning
string Mandatory. This is the string that we will check the length of.
Code Example
<?php
$length = strlen("What is the length of Ariana Grande, Kate Upton, Nicki Minaj, and Selena Gomez?");
echo $length;
?>
79
3. sprintf() definition: The sprintf() function returns a string created by fillingformat with
the given arguments.
Usage: The sprintf() function can be used to assign a formatted string to a variable.
The arg1, arg2, ++ parameters are inserted at the percent (%) signs in the main
string. sprintf() works in a step by step fashion meaning at the first % sign, arg1 is
inserted, at the second % sign, arg2 is inserted, and so on.
format Mandatory. Specifies the string and how to format the variables in it.
Additional format values. These are placed between the % and the letter (example %.2f):
• + (Forces both + and – in front of numbers. By default, only negative numbers are marked)
• ‘ (Specifies what to use as padding. Default is space. Must be used together with the width specifier.
Example: %’x20s (this uses “x” as padding)
• – (Left-justifies the variable value)
• [0-9] (Specifies the minimum width held of to the variable value)
• .[0-9] (Specifies the number of decimal digits or maximum string length)
Note: If multiple additional format values are used, they must be in the same order as above.
arg1 Mandatory. The argument to be inserted at the first %-sign in the format string
arg2 Not Mandatory. The argument to be inserted at the second %-sign in the format string
arg++ Not Mandatory. The argument to be inserted at the third, fourth, etc. %-sign in the format string
Code Example
<?php
$first_name = 'President';
$last_name = 'Business';
?>
4. echo() definition: The echo() function outputs strings and information to the browser.
Usage: You’ll make use of echo() constantly. Technically, echo() is not actually a function
but a language construct. As such, in almost all use cases you will omit the parenthesis
entirely.
Code Example
<?php
?>
5. strpos() definition: The strpos() function returns the position of the first occurrence
of find in string. If specified, the function begins its search at positionstart. Returns false if find is
not found.
Usage: You can use the strpos() function to find the first occurrence of a small string in a
larger string and if the small string isn’t found, strpos() returns false.
Code Example
<?php
$string = '0123456789';
$find = '7';
$start = 0;
echo $result;
?>
7
The code above uses a string of characters that represent numbers as a string. These are
not real numbers, they are of type string not int or float! We simply use this to illustrate that
when using this function the very first character in a string starts with zero. For every single
character including any whitespace, the number increments by one. We start at the first
position of 0 in the example, but had we started at 8 for example, then the function would
have returned false since it was looking for 7, but started looking at the eighth position so it
already missed it.
6. implode() definition: The implode() function does the exact opposite ofexplode() – it
creates a large string from an array of smaller strings.
Usage: Returns a string created by joining every element in the array with separator.
separator Not Mandatory. Specifies what to put between the array elements. Default is “” (an empty string)
Code Example
<?php
echo $string;
?>
Code Example
<?php
$strings = array (
'You like to have a great experience',
'You are a really nice individual',
'Do you like to drink Dunkin Donuts?'
);
$search = array (
'great',
'experience',
'individual',
'Dunkin Donuts'
);
$replace = array (
'fantastic',
'time',
'person',
'Starbucks'
);
$replaced = str_replace ( $search, $replace, $strings );
print_r ( $replaced );
?>
Array
(
[0] => You like to have a fantastic time
[1] => You are a really nice person
[2] => Do you like to drink Starbucks?
)
8. strtolower() definition: The strtolower() function turns a mixed case string into all
lowercase characters.
Usage:Returns string with all alphabetic characters converted to lowercase. The table used
for converting characters is locale-specific.
string Mandatory. Specifies the string that we will convert to all lowercase.
Code Example
<?php
function chill($string) {
$person = 'BUDDY CAN YOU TURN OFF THE CAPS LOCK KEY?!';
9. explode() definition: The explode() function breaks apart a string into an array.
Usage:If you know where the information that you want lies in a larger string, you can
extract it out with the explode() function.
Possible values:
Code Example
<?php
$string = "Your mind is so prodigiously empty that there is simply nothing left to empty out.";
print_r (explode(' ',$string));
?>
Array
(
[0] => Your
[1] => mind
[2] => is
[3] => so
[4] => prodigiously
[5] => empty
[6] => that
[7] => there
[8] => is
[9] => simply
[10] => nothing
[11] => left
[12] => to
[13] => empty
[14] => out.
)
10. chr() definition: The chr() function returns a character when you pass it an ASCII value.
Usage: Returns a string consisting of the single ASCII character ascii.
Code Example
<?php
// Decimal value
echo chr(33);
echo chr(34);
echo chr(35);
// Octal values
echo chr(110);
echo chr(111);
echo chr(112);
// Hex values
echo chr(0x52)
?>
!”#nopR
11. trim() definition: The trim() function cleans a string of all whitespace or other specified
characters.
Usage:Returns string with every whitespace character in charlist stripped from the
beginning and end of the string. You can specify a range of characters to strip
using .. within the string. For example, a..z would strip each lowercase alphabetical
character. If charlist is not supplied, n, r, t, x0B, , and spaces are stripped.
charlist Not Mandatory. Specifies which characters to remove from the string. If left out, all of the following characters
are removed:
• “” – NULL
• “t” – tab
• “n” – new line
• “x0B” – vertical tab
• “r” – carriage return
• ” ” – ordinary white space
Code Example
<?php
$text = ('asdf This is a
cool string with some nonsense characters
asdf');
echo $slim_n_trim;
?>
This is a cool string with some nonsense characters at the start and end, not to
mention some really strange whitespace characters
Code Example
<?php
echo str_repeat('Everything is Awesome! ', 3);
?>
13. strtoupper() definition: The strtoupper() function returns a string with all of it’s
characters converted to uppercase.
Usage:If you know where the information that you want lies in a larger string, you can
extract it out with the strtoupper() function.
Code Example
<?php
$tired = "hey buddy, sorry I didn't get my caffeine yet";
$starbucks = ", but hold up - i'll drink some now.... ... ten minutes later...";
$awesome = strtoupper(" wow I feel awesome!!!");
echo $tired.$starbucks.$awesome;
?>
hey buddy, sorry I didn’t get my caffeine yet, but hold up – i’ll drink some now…. …
ten minutes later… WOW I FEEL AWESOME!!!
14. str_pad() definition: The str_pad() function pads a string to a new length.
Usage: Pads string using pad_string until it is at least length characters and returns the
resulting string. By specifying pad_type, you can control where the padding occurs..
str_pad function signature str_pad(string, length, pad_string, pad_type)
Argument Argument Meaning
length Mandatory. Specifies the new string length. If this value is less than the original length of the string, nothing will
be done
pad_string Not Mandatory. Specifies the string to use for padding. Default is whitespace
Possible values:
• STR_PAD_BOTH – Pad to both sides of the string. If not an even number, the right side gets the extra
padding
• STR_PAD_LEFT – Pad to the left side of the string
• STR_PAD_RIGHT – Pad to the right side of the string. This is default
Code Example
<?php
echo str_pad('Microsoft owns Minecraft ', 53, 'wow!');
?>
15. ord() definition: The ord() function returns the ASCII value of the first character of a
string.
Usage: Returns the ASCII value of the first character in string.
Code Example
<?php
$one = ord('The best way to get an iPhone is to visit your friendly Apple Store');
$two = ord('t');
$three = ord('Hello there good buddy');
84 | 116 | 72
16. strtok() definition: The strtok() function splits a string into smaller strings called
tokens.
Usage: Breaks string into tokens separated by any of the characters in split and returns the
next
token found. The first time you call strtok() on a string, use the first function prototype;
afterward, use the second, providing only the tokens. The function contains an internal
pointer for each string it is called with.
Code Example
<?php
$string = "Please make sure to follow the instructions (or you'll be put to sleep).";
$token = strtok($string, " ");
Please
make
sure
to
follow
the
instructions
(or
you’ll
be
put
to
sleep).
17. strtr() definition: The strtr() function translates certain characters in a string.
Usage: When given three arguments, returns a string created by translating in string every
occurrence of a character in from to the character in to with the same position. When
given two arguments, returns a string created by translating occurrences of the keys
in array in string with the corresponding values in array.
array Required (unless to and from is used). An array containing what to change from as key, and what to change to as
value
Code Example
<?php
$array = array("tech" => "help", "support" => "right now");
echo strtr("Do you need some tech support?",$array);
?>
charlist Not Mandatory. Specifies which characters to remove from the string. If left out, all of the following characters
are removed:
• “” – NULL
• “t” – tab
• “n” – new line
• “x0B” – vertical tab
• “r” – carriage return
• ” ” – ordinary white space
Code Example
<?php
$right_trimmed = rtrim('The prophecy states you are the most interesting person in the world.
cANyOUbELIEVEtHAT?', 'cANyOUbELIEVEtHAT?');
echo $right_trimmed;
?>
The prophecy states you are the most interesting person in the world.
19. md5() definition: The md5() function calculates the MD5 hash of a string.
Usage:Calculates the MD5 encryption hash of string and returns it. If the raw option
is true then the MD5 hash returned is in raw binary format (length of 16), binary defaults
to false, thus making MD5 return a full 32-character hex string.
Code Example
<?php
$str = "Soon, I will be a collection of characters you could never possibly understand.";
echo md5($str);
?>
78e382eb9b9b8c265bb10d3bce8e1608
20. strrpos() definition: The strrpos() function finds the position of the last occurrence of
a string inside another string.
Usage:Returns the position of the last occurrence of find in string, or false if find is not
found.
If specified and positive, the search begins start characters from the start of string. If
specified and negative, the search begins start characters from the end of string.
Code Example
<?php
$position = strrpos("Everything is awesome, everything is cool when your part of a team, everything
is awesome, when you're living the dream!", "awesome");
echo "The last position of 'awesome' is at position $position";
?>
separator Not Mandatory. Specifies what to put between the array elements. Default is “” (an empty string)
Code Example
<?php
$fields = array('This', 'does', 'the same', 'thing as implode()');
$string = join(' @@ ', $fields);
echo $string;
?>
Code Example
<?php
$hex = bin2hex('I am now nothing more than hex');
echo $hex;
?>
4920616d206e6f77206e6f7468696e67206d6f7265207468616e20686578
23. ltrim() definition: The ltrim() function removes whitespace or other predefined
characters from the left side of a string.
Usage:Returns string with all characters in charlist stripped from the beginning.
If charlist is not specified, the characters stripped are n, r, t, v, , and spaces..
charlist Not Mandatory. Specifies which characters to remove from the string. If left out, all of the following characters
are removed:
• “” – NULL
• “t” – tab
• “n” – new line
• “x0B” – vertical tab
• “r” – carriage return
• ” ” – ordinary white space
Code Example
<?php
$left_trimmed = ltrim('cANyOUbELIEVEtHAT? The prophecy states you are the most interesting person in
the world. ', 'cANyOUbELIEVEtHAT?');
echo $left_trimmed;
?>
The prophecy states you are the most interesting person in the world.
length Not Mandatory. Specifies how many characters should be replaced. Default is the same length as the string.
Code Example
<?php
$greet = "Goooooood Morning Vietnam!";
$nyc = substr_replace($greet, "New York!", 18, 7);
echo $nyc.'<br>';
echo $boston;
?>
25. str_split() definition: The str_split() function splits a string into an array.
Usage: Splits string into an array of characters, each containing length characters;
if length is not specified, it defaults to 1.
str_split function signature str_split(string, start, length)
Argument Argument Meaning
length Not Mandatory. Specifies the length of each array element. Default is 1
Code Example
<?php
print_r(str_split('SPACESHIP!'));
?>
Array
(
[0] => S
[1] => P
[2] => A
[3] => C
[4] => E
[5] => S
[6] => H
[7] => I
[8] => P
[9] => !
)
Code Example
<?php
$password = sha1('password');
echo "Hey bud, what's your password? You: Oh it's $password. - Let me know if you have any trouble
logging in.";
?>
string Mandatory. Specifies the string to apply an uppercase first letter to.
Code Example
<?php
$lcfirst = "super cool";
$ucfirst = ucfirst($lcfirst);
echo $ucfirst;
?>
Super cool
28. chunk_split() definition: The chunk_split() function splits a string into a series of
smaller parts.
Usage:If you know where the information that you want lies in a larger string, you can
extract it out with the chunk_split() function.
length Not Mandatory. A number that defines the length of the chunks. Default is 76
end Not Mandatory. A string that defines what to place at the end of each chunk. Default is rn
Code Example
<?php
$sentence = "Eat the Leafy Greens for good health.";
echo $chunked;
?>
29. ucwords() definition: The ucwords() function converts the first character of each
word in a string to uppercase.
Usage:If you’d like to turn the first character of every word into uppercase, this function will
do that for you.
string Mandatory. Specifies the string to convert to uppercase for the first character of each word.
Code Example
<?php
$title = "ten reasons to check out the latest article on something!";
$titlized = ucwords($title);
echo $titlized;
?>
flags Not Mandatory. Specifies how to handle quotes, invalid encoding and the used document type.
Invalid encoding:
• ENT_IGNORE – Ignores invalid encoding instead of having the function return an empty string.
Should be avoided, as it may have security implications.
• ENT_SUBSTITUTE – Replaces invalid encoding for a specified character set with a Unicode
Replacement Character U+FFFD (UTF-8) or &#FFFD; instead of returning an empty string.
• ENT_DISALLOWED – Replaces code points that are invalid in the specified doctype with a Unicode
Replacement Character U+FFFD (UTF-8) or &#FFFD;
Note: Unrecognized character-sets will be ignored and replaced by ISO-8859-1 in versions prior to
PHP 5.4. As of PHP 5.4, it will be ignored an replaced by UTF-8.
double_encode Not Mandatory. A boolean value that specifies whether to encode existing html entities or not.
Code Example
<?php
$entity = htmlspecialchars('<b>Look at me, I am bold</b>. No, no actually you are not, you have been
special chared.');
echo $entity;
?>
<b>Look at me, I am bold</b>. No, no actually you are not, you have been special
chared.
31. stripos() definition: The stripos() function finds the position of the first occurrence of
a string inside another string.
Usage: Returns the position of the first occurrence of find in string using case-insensitive
comparison. If specified, the function begins its search at position start. Returns false
if find is not found.
stripos function signature stripos(string, find, start)
Argument Argument Meaning
Code Example
<?php
$string = 'Just where does that color appear in the string?';
$occurs = stripos($string,"COLOR");
echo "You're in luck because with stripos() I can tell you it is at $occurs";
?>
number Mandatory. The number to be formatted. If no other parameters are set, the number will be formatted
without decimals and with comma (,) as the thousands separator.
decimals Not Mandatory. Specifies how many decimals. If this parameter is set, the number will be formatted with a
dot (.) as decimal point
decimalpoint Not Mandatory. Specifies what string to use for decimal point
separator Not Mandatory. Specifies what string to use for thousands separator. Only the first character of separator is
used. For example, “xxx” will give the same output as “x”
Note: If this parameter is given, all other parameters are required as well
Code Example
<?php
$cash = 5500.257612345;
?>
Code Example
<?php
$clean = stripcslashes($dirty);
echo $clean;
?>
35. strstr() definition: The strstr() function searches for the first occurrence of a string
inside another string.
Usage: Returns the portion of string from the first occurrence of search until the end
of string, or from the first occurrence of search until the beginning
of string if before_search is specified
and true. If search is not found, the function returns false. If search contains more than
one character, only the first is used.
search Mandatory. Specifies the string to search for. If this parameter is a number, it will search for the character
matching the ASCII value of the number
before_search Not Mandatory. A boolean value whose default is “false”. If set to “true”, it returns the part of the string
before the first occurrence of the search parameter.
Code Example
<?php
$sentence = "PHP is a great open source software community.";
36. wordwrap() definition: The wordwrap() function wraps a string into new lines when
it reaches a specific length.
Usage:Inserts break into string every width characters and at the end of the string and
returns the resulting string. While inserting breaks, the function attempts to not break in the
middle of a word. If not specified, break defaults to n and size defaults to 75. If cut is given
and is true, the string is always wrapped to the given width
break Not Mandatory. Specifies the characters to use as break. Default is “n”
cut Not Mandatory. Specifies whether words longer than the specified width should be wrapped:
Code Example
<?php
$str = "Sometimes you will have a string that is quite long and in cases like that you can use the
wordwrap function to make it easier to work with.";
echo wordwrap($str,30,"<br>n");
?>
Code Example
<?php
$str = "Hi Traveler, thanks for stopping by!";
echo $str."<br>";
echo addcslashes($str,'t')."<br>";
echo addcslashes($str,'e')."<br>";
38. parse_str() definition: The parse_str() function parses a query string into variables.
Usage: Parses string as if coming from an HTTP POST request, setting variables in the
local scope
to the values found in the string. If array is given, the array is set with keys and values
from the string.
array Not Mandatory. Specifies the name of an array to store the variables. This parameter indicates that the
variables will be stored in an array.
Code Example
<?php
parse_str("color=Blue&make=Subaru&model=wrx");
echo $color."<br>";
echo $make."<br>";
echo $model;
?>
Blue
Subaru
wrx
Code Example
<?php
echo strcmp("This is a string in PHP!", "This is a string in PHP!").' - ';
echo strcmp("Using strings in PHP is really great!", "PHP strings are fun!").' - ';
echo strcmp("Wow", "Look how easy it is to compare strings");
?>
0–1–1
40. strip_tags() definition: The strip_tags() function strips a string from HTML, XML,
and PHP tags.
Usage:Removes PHP and HTML tags from string and returns the result.
The allow parameter can
be specified to not remove certain tags. The string should be a comma-separated list of
the tags to ignore; for example, "<b>,<i>" will leave bold and italic tags.
strip_tags function signature strip_tags(string, allow)
Argument Argument Meaning
allow Not Mandatory. Specifies allowable tags. These tags will not be removed
Code Example
<?php
$markedup = '<h2>41. substr_compare() <small><strong>definition:</strong> The <code>substr()</code>
function returns a part of a string.</small></h2>';
$rawtext = strip_tags($markedup);
echo $rawtext;
?>
startpos Mandatory. Specifies where to start comparing in string1. If negative, it starts counting from the end of the
string
length Not Mandatory. Specifies how much of string1 to compare
case Not Mandatory. A boolean value that specifies whether or not to perform a case-sensitive compare:
Code Example
<?php
$equal = substr_compare("You won't believe it, but this comparison is equal", "comparison is equal",
31);
if($equal == 0){
echo 'The substrings are equal!';
}
?>
42. setlocale() definition: The setlocale() function sets locale information which refers
to language, monetary, time and other information specific for a geographical area.
Usage:Sets the locale for constant functions to location. Returns the current location after
being set, or false if the location cannot be set. Any number of options for constant can
be added (or ORed) together.
Available constants:
If the location is NULL or the empty string “”, the location names will be set from the values of
environment variables with the same names as the constants above, or from “LANG”.
If the location is “0”, the location setting is not affected, only the current setting is returned.
If the location is an array, setlocale() will try each array element until it finds a valid language or region
code. This is very useful if a region is known under different names on different systems.
Code Example
<?php
echo setlocale(LC_ALL, "US");
?>
English_United States.1252
Array
(
[0] => wicked awesome
[1] => mildy interesting
[2] => really fun
[3] => boring as ever
)
We made 1 replacements!
length Mandatory. Specify the number of characters from each string to be used in the comparison
Code Example
<?php
echo strncasecmp("Awesome", "Awesome",8);
echo "<br>";
echo strncasecmp("Awesome", "aWeSoMe",8);
?>
0
0
45. crypt() definition: The crypt() function returns a string encrypted using DES,
Blowfish, or MD5 algorithms.
Usage: Encrypts str using the DES encryption algorithm seeded with the two-character salt
value salt. If salt is not supplied, a random salt value is generated the first time crypt() is
called
in a script; this value is used on subsequent calls to crypt(). Returns the encrypted string.
salt Not Mandatory. A string used to increase the number of characters encoded, to make the encoding more
secure. If the salt argument is not provided, one will be randomly generated by PHP each time you call this
function.
Code Example
<?php
$secret = crypt('Password123', '$2a$10$1qAz2wSx3eDc4rFv5tGb5t');
echo "Can you guess what the characters of my password are? You can use $secret for a hint.";
?>
Can you guess what the characters of my password are? You can use
$2a$10$1qAz2wSx3eDc4rFv5tGb5eByw4KQDygkPgOmhrh8p0Ix50i4Pujwm for a
hint.
format Mandatory. Specifies the string and how to format the variables in it.
Additional format values. These are placed between the % and the letter (example %.2f):
• + (Forces both + and – in front of numbers. By default, only negative numbers are marked)
• ‘ (Specifies what to use as padding. Default is space. Must be used together with the width specifier.
Example: %’x20s (this uses “x” as padding)
• – (Left-justifies the variable value)
• [0-9] (Specifies the minimum width held of to the variable value)
• .[0-9] (Specifies the number of decimal digits or maximum string length)
Note: If multiple additional format values are used, they must be in the same order as above.
arg1 Mandatory. The argument to be inserted at the first %-sign in the format string
arg2 Not Mandatory. The argument to be inserted at the second %-sign in the format string
arg++ Not Mandatory. The argument to be inserted at the third, fourth, etc. %-sign in the format string
Code Example
<?php
$fahrenheit = 68;
68.00F is 20.00C
47.
quoted_printable_decode() definition: Thequoted_printable_decode() functio
n decodes a quoted-printable string to an 8-bit ASCII string.
Usage:Decodes string, which is data encoded using the quoted printable encoding, and
returns the resulting string.
Code Example
<?php
$str = "Behold=0Athe=0AQuoted=0APrintable=0ADecode.";
echo quoted_printable_decode($str);
?>
Behold
the
Quoted
Printable
Decode.
48. sscanf() definition: The sscanf() function parses input from a string according to a
specified format.
Usage: The sscanf() function decomposes a string according to a printf()– like template
Additional format values. These are placed between the % and the letter (example %.2f):
• + (Forces both + and – in front of numbers. By default, only negative numbers are marked)
• ‘ (Specifies what to use as padding. Default is space. Must be used together with the width specifier.
Example: %’x20s (this uses “x” as padding)
• – (Left-justifies the variable value)
• [0-9] (Specifies the minimum width held of to the variable value)
• .[0-9] (Specifies the number of decimal digits or maximum string length)
Note: If multiple additional format values are used, they must be in the same order as above.
arg++ Not Mandatory. The third, fourth, and so on, to store data in
Code Example
<?php
$string = "LenovotUltrabook (400)";
$a = sscanf($string, "%st%s (%d)");
print_r($a);
?>
Array
(
[0] => Lenovo
[1] => Ultrabook
[2] => 400
)
49. crc32() definition: The crc32() function calculates a 32-bit CRC (cyclic redundancy
checksum) for a string.
Usage: Calculates and returns the cyclic redundancy checksum (CRC) for string.
Code Example
<?php
$str = crc32("Eat Your Leafy Greens!");
printf("%un",$str);
?>
2184231086
flags Not Mandatory. Specifies how to handle quotes, invalid encoding and the used document type.
• ENT_IGNORE – Ignores invalid encoding instead of having the function return an empty string.
Should be avoided, as it may have security implications.
• ENT_SUBSTITUTE – Replaces invalid encoding for a specified character set with a Unicode
Replacement Character U+FFFD (UTF-8) or &#FFFD; instead of returning an empty string.
• ENT_DISALLOWED – Replaces code points that are invalid in the specified doctype with a Unicode
Replacement Character U+FFFD (UTF-8) or &#FFFD;
Note: Unrecognized character-sets will be ignored and replaced by ISO-8859-1 in versions prior to
PHP 5.4. As of PHP 5.4, it will be ignored an replaced by UTF-8.
double_encode Not Mandatory. A boolean value that specifies whether to encode existing html entities or not.
Code Example
<?php
$url = array(
'value' => urlencode('awesome')
);
$link = "http://vegibit.com/themes/vegitalian/index.php?var={$url['value']}";
$html = array(
'link' => htmlentities($link, ENT_QUOTES, 'UTF-8')
);
echo "<a href="{$html['link']}">Bootstrap Themes!</a>";
Bootstrap Themes!
Code Example
<?php
$needtochange = levenshtein("Avenues", "Awesome");
echo "Avenues to Awesome has a Levenshtein distance of $needtochange";
?>
Code Example
<?php
echo strcasecmp("Awesome", "Awesome");
echo "<br>";
echo strcasecmp("AwEsOmE", "awesome");
?>
0
0
53. strcspn() definition: The strcspn() function returns the number of characters
(including whitespaces) found in a string before any part of the specified characters are found.
Usage:Returns the length of the subset of string starting at start, examining a maximum
of length characters, to the first instance of a character from char.
Code Example
<?php
$letters = strcspn("Solid State Storage!", "!");
echo "There are $letters letters before the exclamation point.";
?>
54. strripos() definition: The strripos() function finds the position of the last occurrence
of a string inside another string.
Usage: Returns the position of the last occurrence of find in string using a case-insensitive
search,
or false if find is not found. If specified and positive, the search begins start characters
from the start of string. If specified and negative, the search begins start characters from
the end of string. This function is a case-insensitive version of strrpos().
Code Example
<?php
$scooby = "Scooby Dooby Doo, Where are you Sooby Doo?";
$position = strripos("$scooby","doo");
Code Example
<?php
$number = 777;
$isValidNumber = strspn($number, "1234567890") == strlen($number);
echo $isValidNumber;
?>
flags Not Mandatory. Specifies how to handle quotes and which document type to use.
Code Example
<?php
$str = "<h1>©®™</h1>";
echo html_entity_decode($str);
?>
©®™
57. str_shuffle() definition: The str_shuffle() function randomly shuffles all the
characters of a string.
Usage: Rearranges the characters in string into a random order and returns the resulting
string.
Code Example
<?php
$str = 'abcdef';
$shuffled = str_shuffle($str);
bfdaec
58. stristr() definition: The stristr()searches for the first occurrence of a string inside
another string.
Usage: This is the case insensitive version of strstr().
search Mandatory. Specifies the string to search for. If this parameter is a number, it will search for the character
matching the ASCII value of the number
before_search Not Mandatory. A boolean value whose default is “false”. If set to “true”, it returns the part of the string
before the first occurrence of the search parameter.
Code Example
<?php
$sentence = "PHP is a great open source software community.";
59. strpbrk() definition: The strpbrk() function searches a string for any of the specified
characters.
Usage: Returns a string consisting of the substring of string, starting from the position of the
first instance of a character from charlist in string to the end of the string, or false if none
of the characters in charlist is found in string.
Code Example
<?php
echo strpbrk("Jumping Jack Flash is a Gas!"," ");
?>
61. addslashes() definition: The addslashes() function returns a string with backslashes
in front of predefined characters.
Usage:Returns escaped instances of characters in string by adding a backslash before
them. You can specify ranges of characters by separating them with two periods; for
example, to escape characters between b and o, use "b..o". Multiple characters and
ranges can be specified in characters.
Code Example
<?php
$str = addslashes('Tim said, "This is the best stuff so far"');
echo($str);
?>
mode Not Mandatory. Specifies the return modes. 0 is default. The different return modes are:
• 0 – an array with the ASCII value as key and number of occurrences as value
• 1 – an array with the ASCII value as key and number of occurrences as value, only lists occurrences
greater than zero
• 2 – an array with the ASCII value as key and number of occurrences as value, only lists occurrences equal
to zero are listed
• 3 – a string with all the different characters used
• 4 – a string with all the unused characters
Code Example
<?php
$str = "How many times per week do you eat at Chipotle Mexican Grill?";
echo count_chars($str, 3);
?>
?CGHMacdehiklmnoprstuwxy
63. md5_file() definition: The md5_file() function calculates the MD5 hash of a file.
Usage:Calculates and returns the MD5 encryption hash for the file at file. An MD5 hash is a
32-character hexadecimal value that can be used to checksum a file’s data. If raw is
supplied and is true, the result is sent as a 16-bit binary value instead.
raw Not Mandatory. A boolean value that specifies hex or binary output format:
Code Example
<?php
$file = "somefile.txt";
$md5file = md5_file($file);
echo $md5file;
?>
453753ba5c6198a03deaa724b58c3eec
64. nl2br() definition: The nl2br() function inserts HTML line breaks (<br> or <br />) in
front of each newline (n) in a string.
Usage: If xhtml is true, then nl2br will use XHTML-compatible line breaks..
xhtml Not Mandatory. A boolean value that indicates whether or not to use XHTML compatible line breaks:
Code Example
<?php
echo nl2br("This is a piece of text on line 1.nYet this text is on line 2.");
?>
65. sha1_file() definition: The sha1_file() function calculates the SHA-1 hash of a file.
Usage:Calculates and returns the sha1 encryption hash for the file at file. A sha1 hash is a
40-character hexadecimal value that can be used to checksum a file’s data. If raw is
supplied and is true, the result is sent as a 20-bit binary value instead.
sha1_file function signature sha1_file(file, raw)
Argument Argument Meaning
raw Not Mandatory. A boolean value that specifies hex or binary output format:
Code Example
<?php
$file = "somefile.txt";
$sha1file = sha1_file($file);
echo $sha1file;
?>
f9515988673aae7dc5552d24c06ce947684c6bbb
return Not Mandatory. Specifies the return value of the str_word_count() function.
Possible values:
echo "There are $words words in the sentence 'Super Mario is all you need to have a blast!"
?>
There are 10 words in the sentence ‘Super Mario is all you need to have a blast!
Code Example
<?php
$firstarray = $secondarray = array(
"file1",
"file2",
"file10",
"file01",
"file100",
"file20",
"file30",
"file200"
);
echo "This sort uses standard ordering" . "<br />";
usort($firstarray, "strcmp");
print_r($firstarray);
echo "<br />";
echo "This uses the Natural Order" . "<br />";
usort($secondarray, "strnatcmp");
print_r($secondarray);
?>
This sort uses standard ordering
Array
(
[0] => file01
[1] => file1
[2] => file10
[3] => file100
[4] => file2
[5] => file20
[6] => file200
[7] => file30
)
68. strnatcmp() definition: The strnatcmp() function compares two strings using a
natural order algorithm.
Usage: Compares two strings with case sensitivity and returns a number less than 0
if stringone is less than stringtwo, 0 if the two strings are equal, and a number greater
than 0 if stringone is greater than stringtwo.
Code Example
<?php
$firstarray = $secondarray = array(
"FilE1",
"fiLE2",
"filE10",
"fiLE01",
"fILe100",
"fIle20",
"File30",
"FIle200"
);
echo "This sort uses standard ordering" . "<br />";
usort($firstarray, "strcmp");
print_r($firstarray);
echo "<br />";
echo "This uses the Natural Order" . "<br />";
usort($secondarray, "strnatcmp");
print_r($secondarray);
?>
length Mandatory. Specify the number of characters from each string to be used in the comparison
Code Example
<?php
$equal = strncmp("Awesome people do awesome things.", "Awesome birds fly fast.", 7);
$notequal = strncmp("Awesome people do awesome things.", "Awesome birds fly fast.", 9);
echo "Since $equal is equal, the value is $equal. Since $notequal is not equal, the value is
$notequal.";
?>
Since $equal is equal, the value is 0. Since $notequal is not equal, the value is 1.
70. chop() definition: The chop() function removes whitespaces or other predefined
characters from the right end of a string.
Usage: This works just like the rtrim() function.
charlist Not Mandatory. Specifies which characters to remove from the string.
The following characters are removed if the charlist parameter is empty:
• “” – NULL
• “t” – tab
• “n” – new line
• “x0B” – vertical tab
• “r” – carriage return
• ” ” – ordinary white space
Code Example
<?php
$chopped = rtrim('You really are the most interesting person in the world. cANyOUbELIEVEtHAT?',
'cANyOUbELIEVEtHAT?');
echo $chopped;
?>
In our dependency injection for beginners tutorial, we built up a suite of classes to help us
win the FIFA Soccer world championship. We had a Country, some Players, a Team, and
many supporting methods and properties to accomplish our goal. We actually constructed
our little application in a very top down procedural style. That is to say, we had one big
PHP file that kind of looked like this.
• Class 1
• Class 2
• Class 3
• Client code / Implementation of classes.
This is perfect for learning and tutorial style applications. We can very quickly view
everything that is happening in one simple PHP file. If you would like to build a larger
application however, this approach will begin to fail pretty quickly. Maybe you have ten or
fifteen classes to account for, and many lines of code in your client to implement. One PHP
file is not going to cut it in this case. The convention is actually to create one class per
PHP file. From there, your client can either include the needed classes or autoload them
for use. Let’s try to break our prior application into a proper organization with autoloading.
class Country
{
protected $team;
protected $name;
/root/source/Player.php
<?php
class Player
{
protected $name;
/root/source/Team.php
<?php
class Team
{
protected $players = [];
/root/index.php
In our root directory we also have our client code which looks like this.
<?php
$usa->recruit($player1);
$usa->recruit($player2);
$usa->recruit($player3);
$usa->recruit($player4);
$usa->recruit($player5);
echo '<pre>';
print_r($team->getplayers());
When we try to run our program, things are not looking good!
Fatal error: Class ‘Team’ not found in C:\wamp\www\root\index.php on line 3
include('source/Country.php');
include('source/Player.php');
include('source/Team.php');
$usa->recruit($player1);
$usa->recruit($player2);
$usa->recruit($player3);
$usa->recruit($player4);
$usa->recruit($player5);
echo '<pre>';
print_r($team->getplayers());
There is a better way however, and that is to make use of autoloading with Composer.
Manually including files is not going to scale, and will lead to trouble down the line. Let’s
see how to fix this with Composer.
Usage:
command [options] [arguments]
Options:
--help (-h) Display this help message
--quiet (-q) Do not output any message
--verbose (-v|vv|vvv) Increase the verbosity of messages: 1 for normal output, 2 for more verbose
output and 3 for debug
--version (-V) Display this application version
--ansi Force ANSI output
--no-ansi Disable ANSI output
--no-interaction (-n) Do not ask any interactive question
--profile Display timing and memory usage information
--working-dir (-d) If specified, use the given directory as working directory.
Available commands:
about Short information about Composer
archive Create an archive of this composer package
browse Opens the package's repository URL or homepage in your browser.
clear-cache Clears composer's internal package cache.
clearcache Clears composer's internal package cache.
config Set config options
create-project Create new project from a package into given directory.
depends Shows which packages depend on the given package
diagnose Diagnoses the system to identify common errors.
dump-autoload Dumps the autoloader
dumpautoload Dumps the autoloader
global Allows running commands in the global composer dir ($COMPOSER_HOME).
help Displays help for a command
home Opens the package's repository URL or homepage in your browser.
info Show information about packages
init Creates a basic composer.json file in current directory.
install Installs the project dependencies from the composer.lock file if present, or falls
back on the composer.json.
licenses Show information about licenses of dependencies
list Lists commands
remove Removes a package from the require or require-dev
require Adds required packages to your composer.json and installs them
run-script Run the scripts defined in composer.json.
search Search for packages
self-update Updates composer.phar to the latest version.
selfupdate Updates composer.phar to the latest version.
show Show information about packages
status Show a list of locally modified packages
suggests Show package suggestions
update Updates your dependencies to the latest version according to composer.json, and
updates the composer.lock file.
validate Validates a composer.json
We need a composer.json before anything else, so that init command looks good to us.
This command will take you through the process of creating a project using a
composer.json file. For the purposes of this tutorial, it will create a lot you don’t need, so
once you have your composer.json, simply edit it so you only have an empty file containing
the { and } characters, then run composer install which will generate
the autoload.php file we need. In fact, a few things are now created in our project, let’s
see.
/root
Note we now have a vendor directory in our root.
/root/vendor
As well as a newly created autoload.php file
/root/vendor/composer
And finally, some various supporting files for Composer.
return ComposerAutoloaderInit8ba53b7977ed0d2d530d1c0d7714ddcf::getLoader();
Configure PSR4
We’re almost there. First we need to configure the composer.json file for PSR4
autoloading.
{
"autoload": {
"psr-4": {
"Myapp\\": "source"
}
}
}
Once you declare your namespace, you’ll need to run composer dump-autoload in order to
generate the proper autoloading files. Let’s see.
autoload_psr4.php
<?php
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
'Myapp\\' => array($baseDir . '/source'),
);
require('vendor/autoload.php');
use Myapp\Team;
use Myapp\Country;
use Myapp\Player;
$usa->recruit($player1);
$usa->recruit($player2);
$usa->recruit($player3);
$usa->recruit($player4);
$usa->recruit($player5);
echo '<pre>';
print_r($team->getplayers());
This is perfect, but when we try to run our application, we get an error of: Fatal error:
Class ‘Myapp\Team’ not found in C:\wamp\www\root\index.php on line 9. This is
because we had set a namespace of Myapp. If we declare a namespace via PSR4, we
need to make sure to update our class files to make use of those namespaces.
namespace Myapp;
class Country
{
protected $team;
protected $name;
}
/root/source/Player.php
<?php
namespace Myapp;
class Player
{
protected $name;
/root/source/Team.php
<?php
namespace Myapp;
class Team
{
protected $players = [];
Run composer install and or composer update from the command line. Everything will get
set up for you. Now you can simply place an index.php file in this directly and test out any
of the code we discuss in this tutorial. Your boilerplate in the index.php will look something
like this, make sure not to forget to require the autoload file that composer creates for you.
<?php
require 'vendor/autoload.php';
use Goutte\Client;
// Create a new Goutte client instance
$client = new Client();
We set this up so you won’t get any errors like “cURL error 60: SSL certificate problem:
unable to get local issuer certificate”. If you do not set up your client like above, you may
get these errors!
As we see above, the PHP Simple HTML DOM Parser Library makes use of
a find() method, whereas in FriendsOfPHP Goutte you will typically be making use of
a filter() method to find elements in the DOM. Here are the function signatures for both
of these methods.
find(string $selector [, int $index]) Find elements by the CSS selector. Returns the Nth
Return type may vary. element object if index is set, otherwise return an array of
objects.
note: The find() method varies on what it returns to you based on the parameters you pass
in to it. This can sometimes lead to confusion. On the other hand, the filter() method
always returns a Symfony Crawler instance.
$html = file_get_html('https://httpbin.org');
$crawler->filter('title')->each(function ($node) {
echo $node->text() . '<br>';
// httpbin(1): HTTP Client Testing Service
});
$html = file_get_html('https://httpbin.org');
$crawler->filter('li')->each(function ($node) {
echo $node->text() . '<br>';
});
Result of each test.
Pretty straightforward stuff here. As we can see, the FriendsOfPHP Goutte versions are
typically a little more modern and elegant in their syntax thanks to the use of
their each() function which makes it really easy to iterate over every element with an
anonymous function.
element, element a, h1 Selects all <a> elements and all <h1> elements
element > element p > a Selects all <a> elements where the parent is a <p> element
element + element div + h1 Selects all <h1> elements that are placed immediately after <div> eleme
element1 ~ element2 p ~ h2 Selects every <h2> element that are preceded by a <p> element
[attribute~=value] [alt~=Fork] Selects all elements with a href attribute containing the word “Fork”
[attribute|=value] [id|=\-curl] Selects all elements with an id attribute value starting with “-curl”
[attribute^=value] a[href^="https"] Selects every <a> element whose href attribute value begins with “https
[attribute$=value] a[href$=".org"] Selects every <a> element whose href attribute value ends with “.org”
[attribute*=value] a[href*="bin"] Selects every <a> element whose href attribute value contains the subst
“bin”
:empty div:empty Selects every <div> element that has no children (including text nodes)
:enabled input:enabled Selects every enabled <input> element (simply means one that does not
disabled attribute)
:first-child li:first-child Selects every <li> element that is the first child of its parent
:first-of-type p:first-of-type Selects every <p> element that is the first <p> element of its parent
:lang(language) p:lang(en) Selects every <p> element with a lang attribute equal to “en”
:last-child li:last-child Selects every <li> element that is the last child of its parent
:last-of-type li:last-of-type Selects every <li> element that is the last <li> element of its parent
:nth-child(n) span:nth-child(2) Selects every <span> element that is the second child of its parent
:nth-last-child(n) span:nth-last-child(2) Selects every <span> element that is the second child of its parent, coun
from the last child
:nth-last-of-type(n) span:nth-last-of-type(2) Selects every <span> element that is the second <span> element of its p
counting
from the last child
:nth-of-type(n) span:nth-of-type(1) Selects every <span> element that is the first <span> element of its pare
:only-child span:only-child Selects every <span> element that is the only child of its parent
<?php
//---------------------------------------------------------
//---------------------------------------------------------
// .bash selector test
// Goutte
$crawler = $client->request('GET', 'https://httpbin.org');
$crawler->filter('.bash')->each(function ($node) {
echo $node->text() . '<br>';
});
Now, you’ll notice that the above testing references two target urls. One is
https://httpbin.org, which is a site dedicated to offering this type of testing playground. The
other is a file on a local server consisting of custom HTML markup for test purposes. If you
would like to complete the tests in your own environment as well, here is the markup for
http://localhost/guzzle/domtesting.php.
<html>
<head>
<meta charset="utf-8">
<title>HTML DOM Testing</title>
</head>
<body>
<a href="#">This is link one</a> <a class="simplehtmldom" href="#">This is link two</a> <a title="A
title!" href="#">This link has a title!</a>
<div>Hello Div One.</div>
<div id="hello">This div has an id of hello.</div>
<div id="friendsofphp">This div has an id of foo.</div>
<div class="simplehtmldom">This div has a class of simplehtmldom</div>
<img src="http://placehold.it/350x150"> <img title="placeholder" src="http://placehold.it/350x150">
<div id="levelone">
<div id="leveltwo">
<div id="levelthree">This div is nested three levels deep.</div>
</div>
</div>
<ul>
<li>Apples</li>
<li>Oranges</li>
<li>Bananas</li>
<li>Pineapples</li>
<li>Blueberries</li>
</ul>
<table width="100%" border="0">
<tr>
<th>Make</th>
<th>Model</th>
</tr>
<tr>
<td>Tesla</td>
<td>Roadster</td>
</tr>
<tr>
<td class="motorcycle">Alta Motors</td>
<td class="motorcycle">Redshift MX</td>
</tr>
</table>
<form action="domtesting.php">
<input type="checkbox" name="shelter" value="House">
I have a House<br>
<input type="checkbox" name="shelter" value="Condo" checked>
I have a Condo<br>
Name:
<input type="text" name="name">
<br>
Job:
<input type="text" name="job" disabled>
<br>
<input type="number" min="4" max="9" value="5">
State:
<input type="text" name="state" value="Massachusetts" readonly>
<br>
Username:
<input type="text" name="username" required>
<br>
<input type="submit" value="Submit">
</form>
<div>
<p></p>
<p>Text in a paragraph</p>
</div>
<div>
<p>This first paragraph has text.</p>
<p>Other text in a paragraph</p>
</div>
<div id="notextbud"></div>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
<ul>
<li>one</li>
<li>two</li>
<li>three</li>
<li>four</li>
</ul>
<p lang="en">Do you speak English?</p>
<div> <span>Star Wars</span> <span>Lego Dimensions</span> <span>Minecraft</span> <span>Samsung</span>
</div>
<div>
<p>Yum!</p>
<p>Yo!</p>
<span>Ha Ha!</span> </div>
<div> <span>Contrived Markup!</span> </div>
<table width="100%" border="0" cellpadding="3" cellspacing="3" class="table table-bordered">
<tbody>
<tr>
<td width="50%">mixed find(string $selector [, int $index])</td>
<td width="50%">Find elements by the CSS selector. Returns the Nth element
<strong>object</strong> if <strong>index</strong> is set, otherwise return an <strong>array</strong>
of object. </td>
</tr>
<tr>
<td width="50%">public Crawler filter(string $selector) </td>
<td width="50%">Filters the list of nodes with a CSS selector. </td>
</tr>
</tbody>
</table>
</body>
</html>
All of the testing we have done so far really focuses on using CSS Selectors to query the
in memory DOM to get at the elements we’re looking for. One you have an element or
elements however, what can you do with them? Often times, you just want the actual data
contained in them in the form of text content. For example, you fetch a title tag, but what
you really want is the information that the title tag holds. For this you typically apply a
method to the DOM element(s) you have captured. In the case of Goutte, this means
simply adding ->text() to the captured element like we see in all of the examples so far.
Conversely, in Simple HTML DOM Parser, this is done with a property called plaintext.
You can do even more with Goutte too, such as logging in to a website, fetching links from
reddit, and more.
// Apples
// Oranges
// Bananas
// Pineapples
// Blueberries
// 1
// 2
// 3
// 4
// one
// two
// three
// four
We can be more specific by using other methods, let’s see how.
eq()
Here we make use of the eq() method to find an element at a specific position from within
the node list. Notice we no longer need to iterate over the collection using each().
<?php
// Oranges
slice()
In this example, we try out the slice() method before iterating over the results. We pass the
integers of 3 and 2 to the method. 3 indicates we start at offset 3, while 2 indicates we
want to capture 2 items from that given start point.
<?php
// Pineapples
// Blueberries
reduce()
This example shows using the reduce() method to only return strings that are greater than
2 characters in length.
<?php
// Apples
// Oranges
// Bananas
// Pineapples
// Blueberries
// one
// two
// three
// four
first()
<?php
// Apples
last()
<?php
// four
siblings()
This example is pretty cool. First, we reach in and grab the li at position 2 (this is
Bananas). Then, we call siblings() which gives us only the siblings of that element. Finally
we use each() to iterate over the result.
<?php
// Apples
// Oranges
// Pineapples
// Blueberries
attr()
This is one of those bread and butter methods to make use of. In this example, we find the
one form on the page, then retrieve the value of the action attribute. We have been using
attr() throughout this tutorial, so it should be fairly second nature by now.
<?php
// domtesting.php
nodeName()
Suppose you are filtering by a class name like so, but you need to find what tag this class
is assigned to. For this you can use the nodeName() method.
<?php
// td
html()
If you would like to access all of the HTML inside of a given element, you can use the
html() method.
<?php
$crawler = $client->request('GET', 'http://localhost/guzzle/domtesting.php');
echo $crawler->filter('form')->html();
selectLink()
By making use of the selectLink() method, you can actually navigate to the content you
wish to retrieve. In this example, we visit reddit, click on the ‘top’ link, and find the number
one post at the current time.
<?php
echo $crawler->filter('p.title')->first()->text();
// New York judge arrested by State Troopers for DUI on her way to court
// get currentiterationvalue
$currentiterationvalue = $newarray[$i];
// for each current index value, find the associated old index position
$oldposition = array_search($currentiterationvalue, $oldarray);
jquery gained 3
VueJS gained 6
d3 did not change
meteor gained 2
FreeCodeCamp gained 3
angular.js lost 4
react lost 2
So first off we have an old array of data. In it, we have various JavaScript libraries to work
with. In this first example, we can see it is a simple index based array. The algorithm so to
speak is to begin looping through the newest array of data. On each iteration of the loop,
we want to capture the current iteration value in a variable. With that, we can
use array_search to find this current value as it existed in the old array. Once we have that
information, we check to see if it is a new entry or not. If array_search returns false, then
we know we have a new entry in the new array. In this case, we just say that the new entry
gained whatever the absolute value is from the end of the new array. If array_search
returns an integer value, then we now have the position of the current iterating value in the
old array. With this, we can now set up the logic to see if the value has gained, lost, or not
changed when comparing it’s position in the new array versus the old array. As we can
see, when we run the code it calculates positional differences just like we wanted.
$oldarray = [
'FreeCodeCamp' => 'one',
'angular.js' => 'two',
'd3' => 'three',
'jquery' => 'four',
'react' => 'five',
'meteor' => 'six',
];
$newarray = [
'jquery' => 'one',
'VueJS' => 'two',
'd3' => 'three',
'meteor' => 'four',
'FreeCodeCamp' => 'five',
'angular.js' => 'six',
'react' => 'seven',
];
$oldarray = array_keys($oldarray);
$newarray = array_keys($newarray);
jquery gained 3
VueJS gained 6
d3 did not change
meteor gained 2
FreeCodeCamp gained 3
angular.js lost 4
react lost 2
How To Compare Two Arrays of Data and Calculate Position Differences
Summary
This quick tip type tutorial had a look at how to compare two arrays of data and figure out
the differences of each value in the arrays. You may be able to find all kinds of interesting
applications of this approach.
Have you ever wanted to quickly test small PHP snippets of code, but you
became bogged down in opening up your favorite IDE, preparing a simple
test.php file, loading it in the browser, etc.? Sometimes, all you want to do is
quickly test some logic. Perhaps you’re even just browsing some of the
example snippets at the PHP online manual, and thought it might be nice to just
quickly run these examples and see them in action. Maybe you want to try
refactoring a few things and see how it goes. Sometimes, your everyday
workflow is overkill for these simple situations. There is a perfect solution for
you however, I give you: PHP Console!
Cool! Note that you are given a simple text area where you can write some simple snippets
of PHP, then simply click the Try this! button to execute the code. Just above the text area
is the code result output. If you’re so lazy that you can’t even bring yourself to click a
button to run your code, you also have the option to press ctrl-enter to run your snippet.
It’s a great little learning tool to have, and a fantastic way to test out quick snippets of code
without all the overhead. Maybe you’re just learning about a specific function in PHP such
as the substr php function. Now you can test it out very easily. Let’s see!
Imagine this code.
<?php
Off the top of your head, you probably forget what this even does. No problem, plug it into
the console and test it out.
Maybe you’d like to put the array_unique function to the test. Also, very easy to do. First
let’s look at the code, then give it a test run in the PHP Console.
<?php
$array = [
'Time for a sandwich',
'Time for a sandwich',
'PHP 7 is great',
'PHP 7 is great',
'All about that bass, no treble',
'All about that bass, no treble',
];
$unique = array_unique($array);
foreach ($unique as $u) {
echo $u . '<br>';
}
We input the code into the text area and click Try It! Notice that the array_unique() function
does in fact remove any duplicates and the output looks good. How about creating our own
function right in the testing area. Will it work? Let’s try it out.
A very common thing in PHP is to check if a string contains a specific word. Said another
way, you will often need to check for the occurrence of one string inside of another.
The strpos() function can be used for this. Using this knowledge, let’s create a function that
is a little more user friendly. Here is the code we have come up with.
<?php
if (findOccurrence($haystack, $needle)) {
echo '<em>' . $needle . '</em> is in the haystack';
} else {
echo '<em>' . $needle . '</em> is not in the haystack';
}
We were able to create our own function named findOccurrence() which accepts
Pretty cool!
two parameters. The first is a haystack we will search through and the second is the
needle we will be looking for. Inside of our findOccurrence() function, we use strpos() to
do the heavy lifting for us. This is what is known as a wrapper function. We can make use
of wrappers to customize how we would like to interact with the language. In the example
above we can see that one string definitely does exist within the other string of We can find
an occurrence of one string inside other. Let’s change the needle we are looking for and
see what happens.
This time around we look for Gwen. When we run our function, we can see that it is
working correctly since it reports back to us that Gwen is not in the haystack. Shame, we
love Gwen.
var_dump($dbh);
Now that we know we can connect to the database, let’s try to create a table. The
database pdotest is currently empty, but we’ll create a table to hold a few links. Let’s
create a table in our database using PDO.
<?php
$results = $dbh->exec($sql);
var_dump($results);
With a table now created, we can complete an insert statement using PDO. Let’s insert a
link into our new table. We’ll insert a link for Google.
<?php
$results = $dbh->exec($sql);
var_dump($results);
Now that we have inserted a link using PDO, let’s try to fetch it out of the database to see if
it worked. We’ll use a prepared statement to test this.
<?php
$statement->execute();
var_dump($statement->fetchAll());
This seems to be working great! Let’s now add another link to the database, but
Pretty Cool!
this time we’ll make use of a prepared statement for the insert as well. We will add Twitter
this time.
<?php
$result = $statement->execute();
var_dump($result);
We get back a boolean true which means it worked. Let’s fetch the records again and see
what we get!
It definitely looks like it is working, but notice the duplication of data. This is because by
default, the fetchAll() method in PDO will return the data in two forms. One as an indexed
array, and another as an associative array. This actually works out pretty good, because it
gives you the flexibility to interact with that data however you might like. Another way to
make this work is to tell PDO that you would like objects to work with instead. Let’s see
how.
<?php
$statement->execute();
var_dump($statement->fetchAll(PDO::FETCH_OBJ));
Now it would be easy for example to say you want the href of the second link in the
database. To do this, you could use this snippet in the php debug console.
<?php
$statement->execute();
$results = $statement->fetchAll(PDO::FETCH_OBJ);
echo $results[1]->href;
PHP Psysh and Laravel Tinker
Another method of interacting with PHP at the console is via Psysh. If you use the Laravel
framework, you might be familiar with Tinker which is powered by Psysh. This tool is
officially a REPL or read eval print loop. It makes it possible for you to run PHP code
directly in the console. Let’s try setting up an index based array in Psysh(Tinker in this
case). Do note, that first you must enter the shell by typing php artisan tinker which will
give you the following output: Psy Shell v0.7.2 (PHP 7.0.5-3+donate.sury.org~trusty+1 —
cli) by Justin Hileman.
Now that we have a simple index based array of data, we can inspect it just like we would
expect. Here we test the data with a print_r() and var_dump() of the array.
Let’s test out the commonly used in_array() function which tests to see if a given value is in
an array.
Let’s now quickly create an object to work with in PHP. The quickest way to create an
object to work with in PHP without having to rely on a class is to simply cast an array to an
object. Let’s see how we might do this.
Notice that in this case we are simply assigning an associative array to a variable, but just
preceding the array brackets is the (object) cast to operator. This takes our associative
array and converts it to an object. Notice how it gets output to the screen right away. From
there, we can access individual properties of the object just like we normally would. All of
this is making use of the stdClass built in to PHP. We can even create a new class in the
REPL and test out its functionality. Let’s create a simple Task class right in the console
and complete a task.
Even though the repl only works one line at a time, you can still hit the enter key and go to
a new line, continuing to input code. What you will see is that the prompt changes from
three greater than signs to three dots. This indicates that the console recognizes you are
not finished entering valid PHP code, and you need to finish typing. The first example of
this is where we begin to define our Task class. Notice the three dots on each new line
right up until we finally complete the last closing brace of the class. At that point, null is
output to the screen and we get our standard prompt back. At this point, we have a new
class defined in memory. We can now make use of it! We create a new task to Clean
Desk. We then inspect the completed property and see that it is false. Then we make a call
to the finish() method and complete the task. A final inspection of the completed property
shows us that this is now true. Pretty cool! This type of simple test and run code at a
console is great practice to hone your syntax chops without the help of an IDE to guide you
along.
Chapter 3: MySQL
Introduction to MySQL
MySQL is the world’s most popular open source database and powers all kinds
of different applications in the technology industry. Of course the blogging
platform WordPress uses MySQL as it’s database technology, but MySQL goes
far beyond just basic blog applications. Some of the biggest names in
technology today make use of MySQL, including Twitter, Facebook, Etsy, and
more. We also love working with MySQL when writing PHP either natively, or
with a great framework like Laravel or Codeigniter. These frameworks do a
great job of hiding away the details of how MySQL is working behind the
scenes. While this is great, it is really important to have a good grasp of the
fundamentals. This series of articles will do just that, dig into the nuts and bolts
of what MySQL is, how it works, and how we can leverage its power.
show databases;
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| authdemo |
| blog |
| laratut |
| laravelblog |
| mysql |
| performance_schema |
| repotut |
| test |
| wordpress |
+--------------------+
10 rows in set (0.00 sec)
Congratulations! You just ran the first command of MySQL at the command line. Consider
it a hello world of sorts. In our output, we can see there are a bunch of databases already
present in this installation. Not to worry, we are going to be creating new databases and
tables from scratch.
Nice! Plus one of the design of the site as well. They’re using the Bootstrap Framework
which we are also huge fans of.
http://demo.phpmyadmin.net/master-config/
Another option for working with MySQL if you do not have it installed locally is to visit the
demo page at the phpmyadmin website. Here you can use the SQL tab to run MySQL
commands all day long if you like. Once you test it out, if you like the UI, you can easily
download a copy for use in your own environment.
Characteristics of Spreadsheets
Data is stored in Cells, which can also have built in calculation or formatting information.
You may be familiar with the fact that with a spreadsheet, there can be all kinds of markup
which decorates the data in various ways. Because of this reason, spreadsheets are a
meeting room favorite among the business world. In addition, any time you make an
operation on data within a spreadsheet, that operation creates more data. Because of this,
you will find that you can run into unwanted bloat as you add more and more calculations.
Characteristics of Databases
Databases on the other hand store their information in what we call a Record. The
database will store only the data and values. All formatting and calculations are applied
later. The analogy to MVC or model, view, controller kind of applies here in that just like in
web development where we try to separate out logic from markup, it makes sense as well
to keep formatting and actual data separated with our databases. With databases, when
you perform calculations, sorting and so on, these data operations take place only after the
data has been retrieved. This allows you to display only the result of said calculations,
rather than having to store the result as well. A huge benefit of working with a database is
that you can eliminate duplicate information.
Database Normalization
When working with databases, you’ll often run into the term, Normalization. More
specifically, we’re talking about how to organize fields and tables within the database. For
example, which fields should belong to which tables? Database normalization is the
process of deciding how to organize the data in order to make querying the database at a
later time more efficient. The goal is to organize the tables and fields in the database to
reduce as much as possible any dependency or redundancy. The objective is to isolate
data so that any additions, deletions, or modifications of a field can be made in just one
table and then propagated through the rest of the database using the defined relationships.
This is part of the reason for calling it a relational database.
Forms of Normalization
Third normal form, or 3NF, is the standard to which database design best practices adhere
to. Third normal form includes the First Normal Form as well as the Second Normal Form.
In order to understand 3NF, we’ll have to first observe 1NF and 2NF.
First Normal Form: First normal form is the idea that there is a single value for each field.
Second Normal Form: The table must first be in 1NF, as well as the fact that all of the
information in the table is dependent on what defines the row.
Third Normal Form: The table must first be in 1NF, and 2NF. All of the non defining fields
must be directly dependent on the defining fields.
Beyond the academic definitions of the various forms of normalization, is a key concept to
take away. When designing your database schema, you want to keep your tables as
concise as you possibly can, and may need to break apart tables that have too many fields
into two or more tables with a relation defined. This is the tricky part of learning the ins and
outs of a relational database but once we have a good understanding of database
normalization, we’ll be on our way to better database design.
Acronyms upon Acronyms
As if you didn’t have enough acronyms to keep up with in your day to day life as a web
developer, we’ll be adding a few more to your toolkit for working with databases. Here are
the most common you’ll come across.
• DB: Database
• RDBMS: Relational Database Management System – A relational database
management system is a database management system that is based on the
relational model as introduced by E. F. Codd of IBM’s San Jose Research
Laboratory.
• SQL: Structured Query Language – SQL is a special-purpose programming
language designed for managing data held in a relational database management
system.
• DDL: Data Definition Language – A data definition language or data description
language is a syntax similar to a computer programming language for defining
database schemas.
• DML: Data Manipulation Language – is similar to a computer programming language
used for selecting, inserting, deleting and updating data in a database.
• OLAP: Online Analytical Processing – is an approach to answering multi-
dimensional analytical queries quickly.
• OLTP: Online Transactional Processing – a class of IT applications that facilitates
transaction-oriented systems, usually for data entry and retrieval transaction
processing.
• CRUD: Create Read Update Delete – Perhaps the most common acronym of them
all which stands for Create, Read, Update, and Delete.
+---------------------------------------+
| Tables_in_information_schema |
+---------------------------------------+
| CHARACTER_SETS |
| COLLATIONS |
| COLLATION_CHARACTER_SET_APPLICABILITY |
| COLUMNS |
| COLUMN_PRIVILEGES |
| ENGINES |
| EVENTS |
| FILES |
| GLOBAL_STATUS |
| GLOBAL_VARIABLES |
| KEY_COLUMN_USAGE |
| OPTIMIZER_TRACE |
| PARAMETERS |
| PARTITIONS |
| PLUGINS |
| PROCESSLIST |
| PROFILING |
| REFERENTIAL_CONSTRAINTS |
| ROUTINES |
| SCHEMATA |
| SCHEMA_PRIVILEGES |
| SESSION_STATUS |
| SESSION_VARIABLES |
| STATISTICS |
| TABLES |
| TABLESPACES |
| TABLE_CONSTRAINTS |
| TABLE_PRIVILEGES |
| TRIGGERS |
| USER_PRIVILEGES |
| VIEWS |
| INNODB_LOCKS |
| INNODB_TRX |
| INNODB_SYS_DATAFILES |
| INNODB_LOCK_WAITS |
| INNODB_SYS_TABLESTATS |
| INNODB_CMP |
| INNODB_METRICS |
| INNODB_CMP_RESET |
| INNODB_CMP_PER_INDEX |
| INNODB_CMPMEM_RESET |
| INNODB_FT_DELETED |
| INNODB_BUFFER_PAGE_LRU |
| INNODB_SYS_FOREIGN |
| INNODB_SYS_COLUMNS |
| INNODB_SYS_INDEXES |
| INNODB_FT_DEFAULT_STOPWORD |
| INNODB_SYS_FIELDS |
| INNODB_CMP_PER_INDEX_RESET |
| INNODB_BUFFER_PAGE |
| INNODB_CMPMEM |
| INNODB_FT_INDEX_TABLE |
| INNODB_FT_BEING_DELETED |
| INNODB_SYS_TABLESPACES |
| INNODB_FT_INDEX_CACHE |
| INNODB_SYS_FOREIGN_COLS |
| INNODB_SYS_TABLES |
| INNODB_BUFFER_POOL_STATS |
| INNODB_FT_CONFIG |
+---------------------------------------+
59 rows in set (0.03 sec)
Very slick! You’ll notice we had to specify what database to view tables from. Let’s fix that
by changing the database to use.
mysql> use information_schema;
Database changed
+----------------------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------------------------+--------------+------+-----+---------+-------+
| CATALOG_NAME | varchar(512) | NO | | | |
| SCHEMA_NAME | varchar(64) | NO | | | |
| DEFAULT_CHARACTER_SET_NAME | varchar(32) | NO | | | |
| DEFAULT_COLLATION_NAME | varchar(32) | NO | | | |
| SQL_PATH | varchar(512) | YES | | NULL | |
+----------------------------+--------------+------+-----+---------+-------+
5 rows in set (0.01 sec)
Database changed
Name: 'SHOW'
Description:
SHOW has many forms that provide information about databases, tables,
columns, or status information about the server. This section describes
those following:
SHOW AUTHORS
SHOW {BINARY | MASTER} LOGS
SHOW BINLOG EVENTS [IN 'log_name'] [FROM pos] [LIMIT [offset,] row_count
SHOW CHARACTER SET [like_or_where]
SHOW COLLATION [like_or_where]
SHOW [FULL] COLUMNS FROM tbl_name [FROM db_name] [like_or_where]
SHOW CONTRIBUTORS
SHOW CREATE DATABASE db_name
SHOW CREATE EVENT event_name
SHOW CREATE FUNCTION func_name
SHOW CREATE PROCEDURE proc_name
SHOW CREATE TABLE tbl_name
SHOW CREATE TRIGGER trigger_name
SHOW CREATE VIEW view_name
SHOW DATABASES [like_or_where]
SHOW ENGINE engine_name {STATUS | MUTEX}
SHOW [STORAGE] ENGINES
SHOW ERRORS [LIMIT [offset,] row_count]
SHOW EVENTS
SHOW FUNCTION CODE func_name
SHOW FUNCTION STATUS [like_or_where]
SHOW GRANTS FOR user
SHOW INDEX FROM tbl_name [FROM db_name]
SHOW MASTER STATUS
SHOW OPEN TABLES [FROM db_name] [like_or_where]
SHOW PLUGINS
SHOW PROCEDURE CODE proc_name
SHOW PROCEDURE STATUS [like_or_where]
SHOW PRIVILEGES
SHOW [FULL] PROCESSLIST
SHOW PROFILE [types] [FOR QUERY n] [OFFSET n] [LIMIT n]
SHOW PROFILES
SHOW SLAVE HOSTS
SHOW SLAVE STATUS
SHOW [GLOBAL | SESSION] STATUS [like_or_where]
SHOW TABLE STATUS [FROM db_name] [like_or_where]
SHOW [FULL] TABLES [FROM db_name] [like_or_where]
SHOW TRIGGERS [FROM db_name] [like_or_where]
SHOW [GLOBAL | SESSION] VARIABLES [like_or_where]
SHOW WARNINGS [LIMIT [offset,] row_count]
like_or_where:
LIKE 'pattern'
| WHERE expr
Several SHOW statements also accept a WHERE clause that provides more
flexibility in specifying which rows to display. See
http://dev.mysql.com/doc/refman/5.6/en/extended-show.html.
URL: http://dev.mysql.com/doc/refman/5.6/en/show.html
As we can see here, you are greeted with a wealth of great information relating to the
show command. It gives you a nice overview along with detailed examples. Finally, at the
end of this output, they provide a link for you to go right to the point in the official
documentation for more information. Very nice.
MySQL Introduction Conclusion
This has been a great introduction to database technology as well as MySQL.
We’ll be digging in much further as we move through this web series to make
sure our database interaction skill are up to speed. When we’re writing native
PHP or using frameworks to provide a persistence layer to our application, if we
don’t have knowledge of the fundamentals that our application is effecting, we
could run into some hiccups.
We can start out by taking a look at the schemata table from the information_schema
database.
mysql> show columns from information_schema.schemata;
+----------------------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------------------------+--------------+------+-----+---------+-------+
| CATALOG_NAME | varchar(512) | NO | | | |
| SCHEMA_NAME | varchar(64) | NO | | | |
| DEFAULT_CHARACTER_SET_NAME | varchar(32) | NO | | | |
| DEFAULT_COLLATION_NAME | varchar(32) | NO | | | |
| SQL_PATH | varchar(512) | YES | | NULL | |
+----------------------------+--------------+------+-----+---------+-------+
5 rows in set (0.01 sec)
What we want to do here is focus on that second column named type. This is what tells us
what data type will be stored here. The results here are all of the varchar data type. In
addition, we can see that each field has a specific number associated with the varchar.
This is telling us how many characters can be stored. Let’s quickly define a few data types.
Varcar
This is a very flexible data type for strings, especially when you are not sure exactly how
long the length will be. Names and addresses are common uses for the varchar data type.
Varchar has a maximum of 255 characters per field.
Char
When you know how many characters you need, you can make use of the char data type.
This is a fixed width data type. Therefore, you don’t want to allocate a char data type with a
56 character size if you are only going to use 3 characters. It is best to use char only when
the data to be stored will have the same length. Accuracy counts here.
Text
The text data type is a character string just like varchar and char. It is a variable length
data type which can go up to four gigabytes per field! Use this data type carefully.
MySQL Numbers
There are several ways to store numbers depending on what you would like to store in the
database. Like text data, you want to choose the most appropriate type for the data to be
stored.
DECIMAL
You can store very specific numeric values with the DECIMAL data type. Let’s say you
want to store the cost of a product, and you know that all products are going to be less
than 100. We could specify DECIMAL(4,2). This would instruct MySQL to store four total
digits with 2 digits after the decimal point. This would allow for -99.99 up to 99.99. Note the
four total digits and two digits after the decimal point.
INTEGER
Integers are typically used for a unique id or some similar type of representation. The idea
of integers brings into the concept of unsigned values. Most times, when you’re using
integers, you won’t have a need for negative values. In this case, your integer will be
unsigned.
Another interesting feature of this data type is automatic number assignment. You may be
familiar with the idea of an auto incrementing id. AUTOINCREMENT is usually used in
combination with the UNSIGNED data type. This way, you have an automatically updating,
non negative, integer for use in your tables. This is unique to MySQL, it is not a part of
standard SQL.
ENUM
The ENUM is a fancy looking datatype and may have confused you in the past. Be
confused no more! ENUM simply stands for Enumerated list, and it is perfect for Yes / No
type values to be stored. Instead of storing actual text to represent something in your
application, it stores a number. Behind the scenes however, it is in fact associating that
number to a specific text value. When you query the database, you will see the actual text.
Think of options like free, paid, premium, or admin. With ENUM, you can easily allow for
those 4 options, and do so within a small footprint of memory. Be advised, you can only
choose one possible value. Think of it like a select tag in html.
SET
What if you want to have an array of choices so to speak, yet you would like to have more
than one option selected? This is what the SET data type is for. A SET field can store up to
64 values. You are allowed to store none, some, or all of the available options.
MySQL Data Types Summary
While not the most exciting of things to have to know, data types in MySQL are one of
those bread and butter topics that you just have to be aware of. In this episode, we
covered several data types and what they can be used for. Let’s check out a table here:
This is pretty cool. Basically it breaks down like so. The SELECT is what to get.
The FROM dictates the location to look in, and the WHERE is the condition that will apply.
The LIKE portion uses the MySQL wildcard characters which is just a percent sign, to
search for any data within the posts_table that contains the term ‘laravel’. This outlines the
declarative approach. Notice that query above does not say something like, get all the post
names, loop through each name to see if it contains laravel, then return the matching
results. That would be a procedural approach which is not what we do in MySQL.
Advantages of a Declarative Language
In a declarative language, one benefit is that it is the database itself that figures out the
procedure. All you have to do is tell the database what you want, it will figure out how to
get that result for you. It is the Optimizer which determines which algorithm will most
efficiently get the data that you ask for. This is a very different approach from what you
might be used to in your usual procedural approach to programming. It helps to know up
front that this is how MySQL works, lest you bang your head against the wall trying to
figure out why your procedural approaches are not working in the future when we get into
more detailed queries. You are essentially relinquishing your control to the database,
rather than using your own logic. You need to think of what you want, not how to get it.
Get It? Got It. Good!
Declarative Language Outline
• Efficient to use
• The database chooses the algorithm
• May be harder to debug than procedural
• Paradigm shift for procedural thinkers
mysql>
There we go, we’ve created a database to work with. If you made any errors, MySQL will
provide an audible beep and associated error messages to the console. Now what
happens if we try to create a database and the name we choose is already in use? Well,
let’s find out.
mysql>
Interesting. Now check it out. If we get a warning as the result of executing a MySQL
command, MySQL does not display the actual warning by default. Notice it just says 1
warning, but not what it is. We can dig deeper on our own by issuing the show
warnings command.
mysql>
Collation in MySQL
Collation encodes the rules that govern the correct use of characters for the character set.
It also defines the sort order to use on the data as well as the case sensitivity. Character
sets usually have a corresponding collation. The MySQL documentation will give you the
full overview, or you can find this valuable information at the command line like so.
mysql>
From the output above, we can see that latin1 uses the latin1_swedish_ci collation, and
utf8 uses the utf8_general_ci collation.
and just like that, poof, the database and all associated mission critical data is irreversibly
lost. Of course in real life, there would be backups in place and so on, however this
fictional drama about dropping a database drives the point home. MySQL doesn’t ask you
if you are sure or anything like that, it just happily drops the database along with all
associated tables and data within it. Be careful with dropping databases.
If you try to drop a database that doesn’t exist, you’ll get an error. Let’s see.
We can apply the if exists clause to dropping databases, and get a warning rather than
an error like so.
mysql>
mysql>
Ok, so what just happened? Well, first we changed the database we were currently using
to laravelblog by using the use command. Thanks to a prior tutorial, we already have this
database to work with. Ok, once we changed databases, we need to see the tables
contained in that database. Easy enough, we’ll just use show tables to do so. Now we see
which tables we have. Let’s consider that maybe we want to be able to create a table just
like migrations in a different database. How can we do that? Well first we’ll describe it,
and then we’ll apply show create table to it. This gives us the actual syntax we need to
create the table if we want to. Let’s change databases and create this table then!
mysql>
By describing and reverse engineering our table, we were able to recreate that
Excellent!
table in an entirely different database.
It is worth noting that table creation usually has 3 parts.
• 1. The first part is the table name, this is what comes directly after the create
table command.
• 2. The second part is the column and index definition. These are the fields of the
table. As if this stuff is not confusing enough, somehow it was decided that you can
refer to these things as either columns or fields. Just know they mean the same
thing. This section goes in between parentheses ( ) and multiple column definitions
are separated by commas.
• 3. The third part contains table level options such as the storage engine type,
charset, and comments.
Great! That seemed to work pretty well. Note that when using the command line we can
simply end each field definition with a comma, then hit enter to bring us to the next line for
the next field definition. Once you are finished, just add the closing parenthesis along with
a closing semi colon, then hit enter. This will tell MySQL that you are finished with your
declaration and to execute the commands you have entered.
Conclusion
Nice work friends. We’re making a lot of progress in this MySQL series and hitting all the
stops, soup to nuts. Some of this very well may be a lot of review for many of you. For
others, some of these concepts may be the first time you’ve seen them. Either way, its
good to revisit the basics since foundation level knowledge is key to our development.
So far we’ve been hitting what is arguably the more mundane aspects of
dealing with Database Administration. This would be the DDL or data definition
language portion of working with MySQL. It is by using DDL that we are able to
build and modify your databases and tables. Of course this is needed stuff, we
need a database and some tables before we can start inserting, reading,
updating, and deleting some information. Once we do have our database and
tables in place however, we are ready to start applying some DML or data
manipulation language commands to work with the actual data. Let’s get
cooking!
mysql>
Now we can use the insert command to put some friends into our friends table.
mysql>
Ok, do you notice anything a little strange here? That’s right, we are not required to
provide the columns in the same order with which they were created. MySQL is very
flexible in this sense and as long as you have a one to one mapping between the columns
and values in your insert statement, it will just work. Lets add another imaginary friend
using the alternative syntax.
mysql>
mysql>
So happy to see that both Jim Jones and Emmet Brickowski are our friends. Lest
Fantastic!
you are unaware, Emmet is the special, which prophecy has foretold will be the one to stop
President Business and his use of The Kragle on humanity. There are a couple of things to
remember when using insert. When inserting dates into the database, make sure they are
quoted, otherwise the MySQL engine will perform arithmetic on the value you give if in the
YYYY-MM-DD format. The same goes for entering phone numbers. Also notice that the
birthdate field has a default value in the table definition. This means that when we insert a
record, we can actually leave off that field if we like.
mysql>
Notice that we can group multiple collections of values to enter into our fields by enclosing
them within parenthesis. Each group will be separated by a comma as well. So in the
example above, we were able to add both Rick and Dave as our new friends with
one insert statement. Pretty cool.
Inserts using only values
Another neat feature of the insert command in MySQL is that you don’t even have to
specify the fields you want to insert data into if you don’t want to. Just provide the values,
and make sure that the mapping is correct. So for example, our table has the fields in the
order of first_name, last_name, cell_phone, and birthday. If we want to insert only using
values, we better be sure we provide the values in that order, because if we don’t we will
get an error, or worse if the data type matches what can be stored in that field, it will simply
insert that incorrect data and give you no indication that there was a problem. Let’s test
this out now.
mysql>
Fantastic! Look at our collection of friends now. I really do like that Sofia.
As we can see the typical update command follows the format of:
update table set column1=value1, column2=value2 where
The update command is very powerful. You have the possibility of changing hundreds or
even thousands of rows that maybe you didn’t intend to. As an example if you did
something like the following query,
it would update the cell_phone field, but it would update ALL of the cell_phone fields. Now
every single one of your friends has the same cell phone number, and we know this is not
the case. This is a silly example, however updating something of more importance is no
laughing matter. In addition, there is no undo command, so once you make your mistake,
you are stuck with it. If you are unsure, you can do a select statement first, to see how
many rows the query will match. select and update use the same clauses so we can do
this. If we turn the prior statement into a select, it would look like this:
mysql>
So by using this technique, we can see that 5 rows are going to be updated had we used
an updateinstead of a select. Maybe we only wanted to update Dave’s cell phone number.
In that case, we can first do a select to determine how we will then write the update. Let’s
check this out.
mysql>
In the example above, we now can see that only the one row was update which is what we
wanted. By first writing the select statement, it helped us figure out how to put together
our update statement to get the result we want. Perfect.
mysql>
Much like we can convert an update statement into a select statement so that we can
safely see what will be affected in the database, we can do the same with
the delete statement so that we don’t go deleting all kinds of rows we did not intend to.
Since the delete statement affects all fields, we can simply translate that to an asterisk
when constructing the corresponding select statement. For example:
Using a where clause is a good idea in this case. One other thing to know is that if you try
to delete a row that is already gone from the database, that is perfectly fine. MySQL will
simply give you a query ok, with 0 rows affected.
What if you want to delete all rows from a table, how can we do that? Well, it turns out
there are a couple of ways to do this. One of them doesn’t even use the delete command,
however it is a great way to go about completing this task. If we wanted to get rid of all our
friends, we could do either of the following:
or
It turns out the truncate method is the preferred method. When would you do this?
Consider if you had a table in your database that continually tracks some type of history,
which builds up over time, yet has largely inconsequential data. Every so often, it may
make sense to clear out that table to reduce load on the server. That is an ideal application
for the truncate command.
SELECT in MySQL
We saved the best for last, the select command. Retrieving data from a database is
arguably the most important and powerful aspect of working with databases. We’ve been
using select all along during our examples. If you’ve been using MySQL at all,
the select command really just becomes second nature to you since you use it so much.
The really basic format of the select command is just like this:
select from table where expression
There are many more options you can find in the official docs, so be sure to check those
out once your MySQL skills advance. You’ll find yourself visiting those docs frequently, in
addition to copious amounts of Google Searches, and frequent visits to Stack Overflow.
The best way to get up to speed with select is to simply start hammering out some
commands at your console. We can select individual columns, a combination of columns,
or all columns. Here are some example commands and their output:
As you get better and better at the overall syntax, you can start adding in more clauses
and conditions. There might be a need for distinct data, table joins, group by commands,
order by statements, limits, sort orders, and so on. Their implementation becomes clear
once you find a use case for them.
So it looks like we now have 10 friends which live in seven houses. Some of our friends
are a couple, so they live together. Again, go ahead and use the MySQL command line to
update your tables to reflect something similar to what we have here. If you’re having
trouble, just remind yourself of the commands you’ll want to use in our Data Manipulation
Language episode.
count()
Let’s say we want to see how many rows are in a table. How can we do this? Well,
whenever we do a select * from table type statement, it does also return the number of
rows in the table. This is not ideal however for rows that may have hundreds of thousands
of records, not to mention if there are null values. To count the number of entries with non
null values, we can use count().
Here we are able to count how many home phone numbers exist in our houses table. Note
that all you have to do is pass in the name of the column that you are trying to operate on.
Lest you not believe that this function does indeed only count non null values, let’s go
ahead and decide that one of our couples does not believe in having a home telephone
and set their telephone record to null. The Olivios are about to save a bundle on their
phone bill.
If you do want to include the null values in your count, you can do so. Simply use
the count(*) syntax like so:
We can see we’re back to 7, because this method is including the null value. Another
useful way to apply the count method to our data is to combine it with
the distinct keyword. In our friends table, some of the people have the same last name.
Let’s say we want to find out how many unique last names there are in our friends table.
First we’ll count all of our friends, then we’ll count the number of unique last names among
our friends. Check it out:
Nice One! Here we can see that there are 539 days in between July 4th of 2012 and
Christmas day of 2013. By applying that value to the from_days function, we’ll come up
with a difference of one year, six months, and twenty three days. Finally, by rewriting the
initial datediff expression and wrapping it in the from_days function, we can get the
difference in year, month, days format in one shot.
Current Dates and Times
There are a handful of functions that deal with current dates and times such
as current_date(), current_time(), utc_timestamp(), current_timestamp(), now(),
and sysdate(). We can test them out just like this:
There is a difference between how the now() and sysdate() functions work. now() runs at
the beginning of a query and keeps the same value throughout the lifetime of that
query. sysdate() on the other hand, gives you the exact value at that specific point in time,
regardless of where in the query the operation is. We can use the sleep() function to show
how this works.
MySQL has many built in functions for dealing with strings. Many times, we can
perform these operations using whatever programming language we happen to
be using with MySQL such as PHP. Other times however, it is really helpful to
be able to manipulate strings right in our MySQL statements. In this episode
we’ll take a look at working with strings and doing things like setting them to all
upper or lowercase, reversing their order, replacing characters with other
characters, gluing strings together with concatenation, and much more. Let’s
get right to it!
Strings in MySQL
Likely if you’re reading an article on this website, you are familiar with PHP and it’s many
string functions. MySQL also has some useful ways to operate on strings. Let’s look at a
few of them now.
Using the lower and upper functions
When we make a select query on the database, we can apply a lower or upper function to
string data. In this example, we’ll get all the first names of our friends in lower case with
their last names in uppercase.
Reversing Data
By using the reverse() function, we can easily reverse the output of a query. Here, we’ll
retrieve all first names and reverse their letters:
mysql> select concat(first_name, ' ', last_name) from friends where last_name=
'Olivio';
+------------------------------------+
| concat(first_name, ' ', last_name) |
+------------------------------------+
| Jacob Olivio |
| Mary Olivio |
+------------------------------------+
2 rows in set (0.04 sec)
Cool!We were able to select the Olivios and have a nice formatted output by sticking
together their first and last names with a space in between them.
We can take it a step further with the concat_ws() function. With this function, we can
specify the separator and get as many fields as we like. Let’s test it out with a custom
separator here:
MySQL Operators are your friend in fact. In MySQL, just as in all programming
languages, we have these nifty little things called operators. Operators are
pretty darn important, as they allow us to perform meaningful operations on our
data. Some of the MySQL operators include LIKE, LIKE%…%, NOT LIKE, =,
!=, REGEXP, REGEXP^…$, NOT REGEXP, =”, !=”, IN(…), NOT IN(…),
BETWEEN, NOT BETWEEN, IS NULL, and IS NOT NULL. Wow, that’s a lot of
operators. Yep, it sure is. You might be wondering, so how the heck am I going
to use all of these operators and what are they good for? Those are great
thoughts, and we’ll jump right into some of the more common use cases now.
By including these operators in our select statement, we found that Jim Jones
Pretty Slick!
was the only person from our friends that was born in the Awesome 80's. Be honest, you
love Duran Duran.
Between
It turns out using a combination of greater than or equal to and less than or equal to is a
pretty common scenario. MySQL gives you a dedicated operator to do this same thing with
much less typing. It works just like this:
Voila! You see, it works just the same - Jim Jones is our only Hair Band Hero.
Not Between
Now check it out. I know you like that between operator. Today is your lucky day partner,
because not only does MySQL give you a between operator, they also provide you with
a not between operator. Use this to filter out anything not in a range. So we know anyone
else that wasn't born in the 80's is not so cool. So let's check for the non cool friends now:
Did you see that?! Our not between operator just gave us a list of friends
Jumpin Jack Flash!
not born in the 80's with ease, style, and grace. So cool.
OR
This is a great operator and you may be used to using it in your other programming efforts.
When using JavaScript or PHP, we often use the or operator in conditional branches. Do
this action if this is true, or that is true. We can use it in MySQL as well and it is quite
handy. Let's look for anyone born in 1972 or 1973. Check it:
So we can see that using by using or, we were able to grab results for two scenarios. We
can add many together as well. Let's look for people born in the year 1967, 1970, and
1977.
IN
This operator is also quite useful. Instead of chaining so many or operators together, you
could use the in operator to fetch similar results. Here is the syntax for this approach:
Just like any other programming language or approach, there are many ways to skin the
cat so to speak. We're simply looking at some common approaches, then you get to
choose which works best for you.
Did you notice that we just did two queries right there? The first one
Attention Grasshopper!
returned an empty set, why is that? You would think that Penblan is like Penblanc. We
were looking for all the Penblancs in our table, searching for where something is like
Penblan seems reasonable enough, no? Well, it turns out with like, you either have to
have an exact match or use a wild card. The second query uses a wildcard in the last
character position of the Penblanc last name. You can see that it successfully returns the
two entries for Penblanc in the column when we search this way.
Another scenario with the like operator is in conjunction with the multi-character wildcard,
which in MySQL is the percent % symbol. Imagine we had no clue how to spell Emmet's
last name of Brickowski. If we at least know that the first part of his name starts with Brick,
then we can combine what we know with a multi-character wildcard symbol and get the
data we need. Let's try it out:
I see an Emmet right there, do you?! Man, that Lego Movie is awesome. If you haven't
seen it, you absolutely must! If you get nothing else out of this tutorial - make sure to watch
Emmet save the world in the Lego Movie. You'll have a better day because of it.
The other side of the coin with like is not like. In other words, we can do negation. Let's
practice. Show me everyone who was not born in 1972.
The query above says to use as many wildcard characters as you need until you hit one
letter e, then include all remaining characters to the right of that one. If you're familiar with
regular expressions, this style of searching might ring a bell with you.
How about friends that have a last name which begins with the letter V?
It looks like Emmet, Frankie, Jacob, Jim, Mary, and Sheila all have last names that contain
the letter o.
We’re moving onward in our MySQL Journey! This episode will take a look at
many useful features of the language and how you can use them. As always,
we’ll simply be operating on the data that we already have in the friends table
we’ve been working with so far. We’ll cover features like group by and
aggregate functions. They typically go together, much like peanut butter and
jelly. In addition to this, we’ll look at things such as group_concat, having,
and order by. Sort orders are important as well so we will look at sorting in
ascending order as well as descending order. Lastly, testing out queries using
the limit, offset, and functions with order by will be reviewed. Let’s do it!
Here we can see that there are three couples in our group of friends. The first
Nice Job.
column tells us the last name, and the second column gives us the number of times that
last name occurs. Quite useful.
There are many ways to apply the group by statement when using aggregate functions like
count, avg, min, max, and sum. You’ll need to have a play with all of these on various
tables to see how you can combine them to get the results you are looking for. Let’s try a
query to find the youngest of our friends and group them by their last name.
This query grabs the youngest of our friends and groups them by last name. There are a
few things to note here. The last_name column came back in alphabetical order, but there
are only seven records when we know we have ten friends, why is that? Well in this case,
it almost works like a distinct statement like we see here:
group by can be a little tricky at first but once you try a few tests of your own, you’ll find it
to come easier. Be aware that the field which you use the group by on, needs to also be
part of the selectstatement. Additionally, the group by is applied to the field you want
information on, not the field which gets the aggregate function applied to it. The example
above was looking for information on the last_name field but the aggregate function was
applied to the birthday field.
Group Concat
This is a cool little function we can make use of when working with the group by statement.
This function allows us to stick together, or concatenate, things in a group. Let’s find the
cell phone numbers of the couples in our friends table.
Notice how the cell phone numbers for couples are now concatenated together in the
result set. Now by default, the group_concat function uses a comma to separate the items
being concatenated. If you would like to use a different delimiter, you can so so like this:
Now we are simply using a pipe character instead of the comma. Follow the syntax in the
example above and simply swap out the values you would like to use in your test
environment.
Having
You may have seen this particular keyword in various MySQL syntax you have come
across. So what does the having keyword do? Well, it is used as a type of filter for
aggregates or groups of results. Therefore, it fits right in with the group by clause that we
have been testing out so far. Let’s apply a having clause to our query and see what result
it gives us.
So this is pretty cool. What happens is by using the having clause in our example, we are
telling MySQL to get us all the results, but filter them down to only those that have two. So
since there are two Farmingtons, two Olivios, and two Penblancs, they they are the ones
who get returned in our results.
The above example has two queries to talk about. In the first query we order by the
last_name column. In the second query, we order by the id of the house or house_id
column. Note that by default, MySQL provides results in ascending order. We can change
this by adding the desc clause like so:
Works like a charm! When using order by, we can provide more than one
Bingo Bango!
column to sort on. Let’s sort our friends by house_id and first_name.
The reason why we did two queries is so we could illustrate the difference between using
one or two columns when sorting. Now, we provide the house_id as the first option to the
order by clause. The first field takes precedence! Notice that in both cases, whether we
provide one or two columns to sort on, the house_id column runs from 1 to 7 in order. The
way the second sort works is to look at the results of the first sort, and then apply a sub
sort to the results. This is why you’ll notice that the order of Jacob and Mary is different
between the two queries – even though they both live in house_id 7! Dual sorts can be a
little confusing, so just be sure to practice several different use cases to get the concept
down solid.
It looks like Jack is our oldest friend, but he still has a lot of good years left in him! 50 is the
new 20 after all. What if we wanted to get only the second oldest, how could we do that?
Actually, let’s try a couple of queries. First we’ll find the second oldest, then we’ll find the
third and fourth oldest together. This will provide a nice illustration of how to get the results
you want by using limit and offset together:
Bazinga!This is exactly what we were looking for. In the first query, we have a limit of 1. This
says to take only 1 result. The offset is set to 1 as well. What this says, is that instead of
starting to grab records on the first result, start grabbing at the second. Think zero based
here, just like arrays in other programming languages. In the second query, we have a limit
of 2. This says to fetch exactly 2 records. The offset is set to 2 in this case as well. Using
zero based math, this says to start at the third record. This gives us the third and fourth
oldest friends, just like we were looking for.
Jacob was born on the first, Sofia on the tenth, Mary on the eleventh, Sheila on the twelfth,
Emmet on the fifteenth, Brenda on the fifteenth, Frankie on the seventeenth, Jack on the
twenty third, Dave on the twenty fourth, and Jim on the twenty fourth. Pretty Slick!
Conclusion
There were a lot of different approaches to constructing queries that we covered in this
episode. Whether we were testing out aggregate functions in use with the group by clause,
or selecting data within a specific range using limit and offset – we sure had a lot of fun
practicing our MySQL skills. As always, keep practicing these and others on your own
databases and get your skills sharpened.
Inner Join
There are many different types of joins, however the inner join is the most common one
we’ll see. In all of our queries so far, we’ve been querying the friends or houses tables
independently. Let’s refresh our memory of the structure of these tables.
Do you notice the column that is present in both tables? That’s right, it’s
Verrrrry Interesting…
the house_id that exists in both places. This is going to set us up for some join queries. So
why do they call it an inner join? Observe.
The circle on the left is the friends table and the circle on the right is the houses table. This
visualization shows that they both share the house_id column, and since it is in the middle
of the diagram, it is called an inner join. Now let’s practice some queries using the inner
join. There are a few things to be aware of, so we’ll complete several queries and then
discuss. In addition, we’ll add a few more friends to our friends table. These new friends,
Heather and Sandy, are free spirits. They travel constantly and have no permanent home
address. Therefore, their house id is going to be null. Keep this in mind when we get to
outer joins later on in this episode. In fact, let’s just add them to the database now so we
don’t forget:
Notice in the first line of the MySQL above that we are selecting columns from both the
friends table and the houses table. This is what the inner join allows us to do. So if we
were to read the query in plain English, it might sound like “Give me the first name, last
name, and address of my friends from the friends and houses tables and use the house id
as the common field”
Inner Join On
We’ll now do a query that will get us the same exact results, but using a different syntax.
This one will use the on syntax.
Notice that we get the same results, yet our query looked a bit different. Again, we can
read it in plain English to better understand it. The query might sound something like, “Give
me the first name, last name, and address of my friends from the friends and houses
tables on the condition that the house id in the friends table is equal to the house id in the
houses table.”
As we can see, this works just fine if you prefer to save yourself a couple of
Excellent!
keystrokes.
Outer Join
Now comes the outer join. It’s best to understand the inner join before you tackle the outer,
so re read the section above if you need to cement the idea in a little more. With the outer
join, we can have left joins, or right joins.
Left Join
The left join looks like this from a visual perspective. What this is trying to convey is that
we will display all records from the friends table and match with anything in the houses
table that matches. If there are no matches, we still want to see the records from the
friends table. This is the key point, it is less restrictive than the inner join.
Awesome! Notice that our free spirited and homeless friends Heather and Sandy are now
presented in the results. They were no where to be found when we were doing inner joins
in the prior section!
Right Join
For every action, there is an equal and opposite reaction. In this case, for every left there is
also a right. Just as we have a left join, there are also right joins. The visual for this guy
looks like the following. In this case, it is the right side that takes precedence. In reality,
these queries actually do pretty much the same thing. There are edge cases, but mostly
they are interchangeable.
The syntax gets switched around a bit, and looks like this:
Conclusion
This is not only the conclusion of this episode, but the conclusion of our ten part series on
working with MySQL. It has been a lot of fun, and hopefully you picked up a nugget or two
of useful MySQL information along the way.
MySQL Tutorials For Beginners
• http://www.sqlishard.com/
• http://sqlteaching.com/
• http://www.graspsql.com/
• http://sqlzoo.net/
SQL Zoo is monster interactive SQL tutorial
website that covers and entire range of concepts you’ll need to be successful
working with relational databases. Again, this website also offers the ability to run
real queries and learn from the results you get back. Using this hands on approach is
key to really absorbing the material.
• http://sqlcourse.com/
• http://sql-tutorial.ru/
This SQL Tutorial website is an experiment in
creating an interactive textbook experience for the means of teaching the syntax and
use of the SQL programming language. It is very well executed, and a nice model for
the practice of distance learning via interactive textbook style.
• http://philip-greenspun.com/sql/
• http://sql.learncode-thehardway.org/
Whey anyone would want to do something the
hard way, I have no idea. Most would prefer the easiest way possible. No matter, this
is a great website and resource for learning about working with the SQL language
through a large collection of well crafted exercises. Remember, no pain, no gain – do
it the hard way.
• http://code.tutsplus.com/-articles/sql-for-beginners
• http://lynda.com/-mysql-training-tutorials/
You can always count on Lynda to find some
really excellent learning resources for whatever it is you want to learn. The Lynda
tutorials make use of MySQL in conjunction with PHP, Linux, and Apache – so you’ll
feel right at home as a web developer honing your SQL programming skills.
• http://dev.mysql.com/
• http://sqlformat.org/
SQL Format is really a super useful website to
help you with your SQL queries. While not a tutorial website, it is a great tool to plug
in some of your queries, and get them back prettified, and formatted beautifully. Why
is this useful? You’ll find that once your queries start getting really complex and you
begin to lose track of what they even do, having a tool to properly format and indent
them automatically for you will bring you untold joy and happiness.
• http://tutorials-point.com/mysql/
• http://mysql-tutorial.org/
This entire website is dedicated to learning and
mastering the MySQL language in an easy and fun way. Included are examples that
dovetail right back into the teaching material which will solidify the topics covered. Go
from the basics, to stored procedures, sql triggers, views, functions, tips, tricks, and
more.
• http://zetcode.com/-databases/mysqltutorial/
• http://sqlfiddle.com/
SQL Fiddle comes last, not because it is not
awesome, because it is, but because you really do need to have some of the basics
down before you try to make use of it. SQL Fiddle is a great tool you can use right in
your browser to test and share all kinds of database problems and challenges along
with their solutions. You’ll often find answers to database problems on Stack
Overflow with a link to SQL Fiddle for reference. Think of it like an advanced pastebin
for SQL.
• http://www.sqlbolt.com/
• https://www.khanacademy.org/-computing/computer-programming/sql
If you made it this far and you are still ready to
hone your SQL skills, then you are in great luck. One of the best resources available
today, Khan Academy, now has a full blown course on the SQL language. A nice
bonus is that not only are the basics covered, but even more advanced queries as
well.
Chapter 4: JavaScript
Platform Agnostic
Any time we work with a programming language, we have a sense of the development
environment in use. For example if your application is an iOS app, your development
environment probably consists of the Objective C language, being written on an Apple
Computer, using the Xcode IDE. Contrast this with .NET application that would be aligned
with the C# language, on a Windows PC, using the Visual Studio IDE. JavaScript on the
other hand is not really tied to a platform environment. If you want notepad.exe to be your
IDE of choice, you can do that!
Benefits of Firebug
The benefits of Firebug are many, here are some of the key features that are really helpful.
Easy to Launch and Use
Firebug maintains a simple icon in the browser once it is installed. You can easily enable
or disable the service, arrange the console to your liking, and configure which websites
you want it to run for.
HTML Inspection and Editing
Firebug makes it easy to inspect the HTML source of a webpage, or even edit it live and
on the fly. The DOM and webpage will update in the browser in real time as you make
changes. This is a super slick and valuable testing feature.
Debug CSS Designs
It’s easy to see exactly what CSS is affecting which elements on the webpage with
Firebug. Being able to isolate CSS in this way will save you hours of time and frustration.
JavaScript Debug and Profiling
In firebug you can set breakpoints and step through the JavaScript code in real time. It
makes debugging and troubleshooting much easier, as it allows you a window into the
actual workings of the code. The profiler will narrow down any spots in the script that might
be slowing your app down.
Simple JavaScript Testing
This is my favorite feature of Firebug. If you’re used to programming in PHP or another
language, you’ll know that many times in testing, it is a tiring process of edit file, save file,
refresh browser, observe result. Wash, rinse, repeat. With the Firebug command line, we
can simply type some lines of JavaScript and then click, Run. Poof! The JavaScript
executes, and we smile
Here is our first line of JavaScript and we can run it right in the Firebug console with ease!
alert('Getting Started With Javascript Programming!');
Web Concepts
JavaScript is often referred to as one of the 3 core components of web pages.
• HTML The HTML is the markup language of the web page which envelopes our
content. HTML files may be hand written, or dynamically created via a server side
programming language such as PHP. Worth noting is that JavaScript can work on
the server as well in the form of node.js, however that will be for another tutorial.
• CSS CSS is the design language of our web pages. When we have the markup in
place, there needs to be a way to add some style to that markup, lest we have a
majorly bland design. Cascading Style Sheets are what do this for us.
• JavaScript JavaScript is what we’ll be focusing on here. It is what gives the ability to
add interactivity and behavior to a web page. The beginning concepts of JavaScript
are very easy to understand, but as we get into the more advanced features of the
language such as Object Prototypes and such, we’ll see the mind bending abilities of
JavaScript.
We’re moving into the wild and wonderful world of JavaScript programming.
Before we start trying to be a skilled Ninja, we need to first spend some time in
the dojo to hone our techniques. In other words, we won’t try to run before we
first learn to walk. In this episode, we’ll take a look at the structure of the
JavaScript language. Let’s jump right in!
<body>
<h1>This is a web page.</h1>
<p>This webpage is about as simple as it gets. It will make it easy for you to understand the
JavaScript Embedded within it.</p>
JavaScript is:
<up>
<li>deep</li>
<li>dark</li>
<li>delicious</li>
</up>
<script>
alert('I am the JavaScript Victim');
</script>
</body>
</html>
JS is Case Sensitive
In working with technology, us web developers are exposed to numerous different
languages and syntax. Some of the languages we encounter are case insensitive, but
JavaScript is case sensitive so make sure to keep this in mind. You will find things
breaking and not working with simple case errors. For example alert(‘I am the JavaScript
Victim’); works fine whereas Alert(‘I am the JavaScript Victim’); will fail in spectacular
fashion. Actually, it won’t be all that spectacular, in fact the only thing that would tip you off
that something went wrong is, nothing would happen. Such is the nature of JavaScript, it is
a tricky language to debug, but more on that in a later lesson.
The space between var and chimmy is actually needed here for the script to work properly.
Or consider:
document.writeln('This is a line');
Comments in JavaScript
JavaScript comments work just like they do in most other C based languages. You can
make use of the well known multi line and or single line comment techniques. As you likely
know, /* */ handles the multi line commenting while // can be used line by line, or at the
end of a line to add a comment.
The Order of Code Execution Matters
As we mentioned earlier, when a web browser begins it’s interpretation of a web page, it
starts at the top and goes line by line downward through the DOM. This includes the
HTML, CSS, and JavaScript in the page. In our first little snippet of JavaScript, we made
use of the oh so loved alert box to let the visitor know that we are a victim of JavaScript.
Note that the HTML is rendered in the background, and page execution has halted once
the alert message popped. The user must click ok to finish the program. Let’s make a very
minor modification to that web page. We will simply move our script from the body to the
head portion of the page. Let’s see what happens.
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>JavaScript Code Structure</title>
<script>
alert('I am the JavaScript Victim');
</script>
</head>
<body>
<h1>This is a web page.</h1>
<p>This webpage is about as simple as it gets. It will make it easy for you to understand the
JavaScript Embedded within it.</p>
JavaScript is:
<ul>
<li>deep</li>
<li>dark</li>
<li>delicious</li>
</ul>
</body>
</html>
Note that we get the same JavaScript alert on that page. Do you notice something different
though? That’s right, if you look at the background, absolutely no HTML has been
rendered yet, and we are frozen in this state until we click ok. This shows that the order of
execution is indeed important. This is an overly simple example, but you would be
surprised as you move along in your JavaScript journey when you are debugging tricky
problems to find out that simply moving your code up or down in the hierarchy of the DOM
may solve your issue. It may seem trivial, but it does make a difference.
Conclusion
This was a very gentle primer of what’s to come. It has been helpful to review some of the
key points and overview of the language.
All programming languages have a need for variables, for without them, we
wouldn’t be able to get much done! Variables will allow us to keep track of all
kinds of data such as a customer email, the position of an image, or the text
from a form. It can hold whatever we need it to for our programs to work. The
variable is the named container or small piece of computer memory that holds
our data. Moving beyond variables, we’ll start looking at conditional statements.
Let’s take a closer look!
The keyword var is part of the JavaScript language and is used to declare a variable. We
simply use the keyword var followed by the name we want to use to identify our spot in
memory which will hold our data. We are free to name our variables anything we want, so
go crazy! Be sure to use something descriptive that may describe what you would like to
contain inside. Actually, we can name it almost anything, but keep these points in mind:
Variables are written as one word and can be made up
of letters, numbers, underscores, or $ signs. There are no spaces and the order of
numbers is important. For example:
var 10tips;
The = sign is the assignment operator. It is an instruction or command, it does not hold the
traditional equals meaning!
note:We have been talking a lot about that var keyword, and if you have done some
JavaScript programming you will know that sometimes, you see variables defined with
no var keyword. What is that all about?! Well, this is another area, much like semicolon
insertion, where JavaScript is attempting to allow you to be sloppy. Resist the urge! If there
is no var keyword present, JavaScript will look for an existing variable of that name and if it
doesn’t find one, will create it. By leaving off var, you can encounter unexpected results,
and make debugging more difficult than it needs to be.
Case Sensitive Variables
JavaScript Variables are also case sensitive. This is important! If you have a variable in
your program such as y = 10, and then later on in the program you need to update that
value say to 100, if you mistake the case like so Y = 100, no errors will be thrown and you
will have no idea that you just created a second variable with the value of 100, and your
first variable will remain at 10! It pays to be careful with your JavaScript case.
Multiple Variable Declaration
You can declare several variables at once by separating with commas:
var year, month, day;
Weak Typing
In a language like C, on which JavaScript borrows some of its syntax, you need to specify
the type a variable will hold upon declaration. JavaScript has no such requirement and this
is what is called, a weakly typed language, the same as PHP. With a weak type system,
you simply declare your variable and then assign whatever you want to it. This could be a
string, number, boolean, object, function, or array.
var x;
x starts as undefined
x = 200;
x is now true
x = false;
x is now false
Undefined
undefined means a variable has been declared but has not yet been assigned a value.
Null
null is an assignment value. It can be assigned to a variable as a representation of no
value.
Number
JavaScript has a single number type. Internally, it is represented as 64-bit floating point.
Unlike many other programming languages, there is no separate integer type,
so 7 and 7.0 are the same value. This is a nice feature since we do not need to worry
about overflow in integers. This helps to avoid numeric type errors.
String
A string can use single or double quotes. I prefer to use single quotes in my JavaScript,
and double quotes in JSON. This way, it help to lessen confusion between the two. All
characters in JavaScript are 16 bits wide. JavaScript does not have a character type. To
represent a character, just make a string with one character in it. A cool feature in
JavaScript stings is the length property. You can find a strings length by doing something
like
var string = 'Just throw yo hands in the air';
console.log(string.length); // 30
Booleans
true or false
Conditional Code
Beyond very basic JavaScript one line commands, we need to start being able to ask
questions in our code, and run blocks of code that only execute under specific conditions.
The first conditional we’ll look at is the oh so reliable and popular if statement.
if ( example == true ) {
alert('Yes!');
}
We need to get some terminology straight at this time as well in the form
of parentheses, brackets, and braces.
( these are parentheses! )
[ these are brackets! ]
{ these are braces }
These guys always come in pairs, an opening will always have a closing.
We can see the if statement puts a condition within parentheses, followed by some code
contained between braces. The code between the braces only runs if
the condition between the parentheses is true! In this example there is only one
JavaScript statement to run, however you could include thousands of statements in
between those braces to run! That would likely not happen though
The condition between parentheses must evaluate to either true or false. All conditions
must boil down to simply true or false.
Equality in JavaScript
If in the condition you are asking if something is equal to something else, you will never
use the single = sign! As we already discussed in variables, the = is used only to assign a
value. It reads right to left in a sense. Take this value on the right of the = sign and assign it
to the name on the left of the =.
double equals
A comparison using the double-equals operator will return true if the two things being
compared are equal. There is a bit of a catch with the double-equals though, and that is if
the comparison being made is between two different types of values, type coercion is the
result. This can cause some strange things to happen:
console.log(712 == "712"); // true
console.log(0 == false); // true
triple equals
This is why the masters of JavaScript recommend to use the triple-equals operator as this
type coercion is avoided. If we rerun the example using the triple-equals, we’ll get
something more along the lines of what we might expect:
console.log(712 === "712"); // false
console.log(0 === false); // false
Just like other programming languages, you can make use of the switch statement as
well:
var theday = new Date().getDay();
switch (theday) {
case 0:
day = "The Day is Sunday";
break;
case 1:
day = "The Day is Monday";
break;
case 2:
day = "The Day is Tuesday";
break;
case 3:
day = "The Day is Wednesday";
break;
case 4:
day = "The Day is Thursday";
break;
case 5:
day = "The Day is Friday";
break;
case 6:
day = "The Day is Saturday";
break;
}
Try running this code in your firebug console and see what day it is for you!
Moving on in our journey of the JavaScript language, we can now take a look at
some additional building blocks of our JavaScript code, and that would be in the
form of JavaScript Operators and Expressions. Much like peanut butter and
jelly, or Celebrities and The Paparazzi, operators and expressions go together.
So let’s go ahead and jump right into JavaScript Operators and Expressions.
JavaScript Expressions
One of the main things we do with programs is to evaluate a condition and take action
based on that condition. When we write a line of code that can be evaluated to a value,
this is what’s called an expression. Even the simplest lines of code can be an expression.
Extremely simple expressions are called primary expressions yet the more complex
expressions are what we are more interested in. We can build these complex expressions
using various combinations of the primary expressions.
JavaScript Operators
We need to make use of operators in our code so that we can update, move, and modify
our data. We do this with operators. Operators are simply the symbols used for this
purpose. Let’s check them out.
+–*/
if ( x = y ) {
// always true no matter what!
}
and
count += 3;
This shorthand technique works with addition, subtraction, multiplication, and division.
+= -= *= /=
If there was a need to change the operator precedence we could rewrite the expression
like so to alter the result to 100. The main idea is to remember that by using parentheses,
you can set the precedence in your JavaScript as needed. In the following table, the
operators at the top have the highest precedence, and the lowest of course have the
lowest precedence.
result = (7 + 3) * 10;
Operator Precedence
. [] ( ) Refinement and invocation
+– Addition/concatenation, subtraction
|| Logical or
?: Ternary
OperatorOperation
++ Pre- or post-increment
–– Pre- or post-decrement
– Negate number
+ Convert to number
~ Invert bits
+– Add, subtract
+ Concatenate strings
| Compute bitwise OR
|| Compute logical OR
var undefined;
console.log(typeof(undefined));
Here with this single line of code, we create a variable that can store multiple things inside
of it. Essentially, we are assigning an empty array to the variable named manyvalues.
var manyvalues = [];
We can now populate that variable in many different ways. Let’s check out some of the
ways we can do this.
Assignment By Index
We can explicitly assign a value to any index we choose.
var manyvalues = [];
manyvalues[0] = 'I am an Array!';
manyvalues[1] = 'Arrays are Zero Based!';
manyvalues[2] = 8675309;
manyvalues[3] = true;
manyvalues[4] = function () { return 'functioning' };
console.log(manyvalues);
Wow! Check that out Henry! We can put whatever we like into the various containers of our
array. We can put a string, number, boolean, function, object, or whatever. Our array will
happily contain the values we assign.
We can easily set and get by index. We have set some values by index to our array, now
let’s retrieve them:
console.log(manyvalues[0]);
console.log(manyvalues[1]);
console.log(manyvalues[2]);
console.log(manyvalues[3]);
console.log(manyvalues[4]);
This produces the exact same result, and it saves us a bit of typing. Note that due to
JavaScript essentially ignoring whitespace, we can format the syntax as we did here to
make it a little more readable. This is the same example again with all spaces removed.
You can use whatever format you feel comfortable with, as long as the syntax and
delimeters adhere to the JavaScript rules.
var manyvalues=["I am an Array!","Arrays are Zero
Based!",8675309,true,function(){return"functioning"}];
console.log(manyvalues.length);
The camel case is not required but only used to display the object portion and method
portion of the expression more clearly.
Array.reverse()
This nifty built in method takes an array, reverses the contents of said array, and returns
the resulting new order. Recall our manyvalues array, let’s go ahead and reverse it!
var manyvalues = ['JavaScript','Web Design','Social Media'];
manyvalues = manyvalues.reverse();
console.log(manyvalues.length);
Array.pop()
Popping a value off of the end of an array is useful in many instances. Here is an example
of using .pop()
var manyvalues = ['JavaScript','Web Design','Social Media'];
var social = manyvalues.pop();
console.log('Google Plus is great for ' + social);
// Google Plus is great for Social Media
The Mozilla Developers Network has heaps more information about JavaScript Arrays, feel
free to check them out.
This snippet above scans through all HTML elements on the page, and places them in a
variable called aptly, elements. Now depending on what page you run this snippet on, you
will get a different result. When I try this experiment while on the gawker.com home page, I
show 1723 elements as the length of the array. Pretty Cool! We’ll usually be using this in a
more refined way like grabbing all p tags or all div tags.
Wrapping up with arrays, we’re going to be using them all the time in JavaScript. Arrays
are dynamic, in that they are easily modified and read, they are zero based just like most
other programming languages, they are easily identified via the square bracket notation,
and they have a number of useful built in methods to help us with computing the data
which they may contain.
JavaScript Numbers
Working with JavaScript Numbers is a little different than other programming languages.
Experienced programmers will look at a number in JavaScript and wonder, is it an integer,
a float, a double, what is it? Well in JavaScript, there is only one number type. JavaScript
uses 64 bit floating point numbers, no matter what. So if you see a number, it is
essentially floating point, and you don’t have to worry about type conversion between
integers and floats like you would elsewhere.
When we specify numbers, no special convention is necessary, all of the following are
numbers in JavaScript:
var x = 1;
var y = 2.1;
var b = -1986651.12346;
var g = 10987.12394871356;
Yes! This logs out the number 2000, just like we would expect. So the 500 and the 1500
are real numbers, as they are not surrounded by quotes. What if they were? Let’s see:
var number1 = '500';
var number2 = '1500';
Well, this is a very different result! The reason, is that in the second example, the numbers
are actually of data type string. When we use the + sign with strings, it
simply concatenates the two items together. Just like in PHP where you can combine two
strings together with a dot . operator, in JavaScript we use the + plus operator.
So what happens if you try to do this when one of the variables is a string, and the other is
a number? We can test this now:
var number1 = 500;
var number2 = '1500';
In this instance, we get the same result as if they were both strings. That is because when
using the + operator, if one of the operands is a string, the whole expression is treated like
a string. Let’s take it a step further and multiply the two operands together and see what
happens:
var number1 = 500;
var number2 = '1500';
In contrast to the + operator, the * operator will assume both 500 and ‘1500’ are both
numeric, and the product comes out to 750000. Well. Let’s throw some real challenges to
JavaScript. We’re now going to take 500 and multiply it by chicken. Let’ go:
var number1 = 500;
var number2 = 'chicken';
There it is. The dreaded NaN, the Not a Number. NaN is like a mythological creature, born
of legend, highly misunderstood, infinitely confusing and frustrating. NaN has always felt
slippery to me, it’s meaning and use is tricky. Often times, when we see NaN, it means
something went wrong somewhere with type conversion. While weak typing is great for its
expressiveness and ease of use, it can lead to sloppy code, so be careful! Thankfully, we
do have the function isNaN() to help in our JavaScript code:
var num = 'twenty two';
if ( isNaN(num) ) {
console.log('Your num is NOT a Number!');
}
// Your num is NOT a Number!
This way you can be sure your numbers are actually numbers when using them in your
JavaScript programs.
This is just a small sample of the many methods available to you of the Math Object in
JavaScript. To learn more about the additional ones for your use and pleasure, simply visit
the Mozilla Developers Network and have a ball.
JavaScript Strings
Now we get to take a close look at strings in the wonderful world of JavaScript
programming. When dealing with the web, strings are literally everywhere, and we’ll be
working with them no matter what language we are currently making use of. Enough about
that however, we’re talking JavaScript Strings here so let’s check it out.
Just like the Array Object, we have the length property to tell us right away how long the
string is. In a sense, the string is merely an array of characters, so it’s not a huge leap to
get the idea that the length property works on both.
I’m guessing you are beginning to see a pattern here Yes grasshopper, strings also
have methods, and they are quite useful in fact. Let’s check them out:
var lyric = 'We made it through the cold';
var words = lyric.split(' ');
console.log(lyric.split(' '));
// ["We", "made", "it", "through", "the", "cold"]
There are a lot more about JavaScript string methods to know, so when in doubt, just head
over to the MDN, and have a look.
var y2k = new Date(2000, 0, 1); // year month day, month is zero based
var somedate new Date(2014, 5, 3, 10, 55, 32); // year month day hours minutes seconds
Creating Objects
One of the ideas of Objects is to be able to group together data and actions that might be
related. If we were working with a car in our JavaScript program, maybe we define some
variables like so:
var carColor = 'Yellow';
var carTires = 'Firestone';
var carHorses = 300;
var carSlow = false;
This is great, and it works just fine. These are related items however, and why not group
them together in an object? Well, we can do that quite easily:
var car = new Object();
car.color = 'Yellow';
car.tires = 'Firestone';
car.horses = 300;
car.slow = false;
Now we have a car object, and we simply assign it properties as we choose. There is that
mutable behavior it has. Your object needs a value or property associated with it? Simply
use the dot . syntax and assign as needed. Your properties magically come into being,
just like that.
Shorthand Object Creation
The prior example is one way to create an object in JavaScript. There is an easier way to
do this and achieve the same result:
var car = { color: 'Yellow', tires: 'Firestone', horses: 300, slow: false };
Having this all on one line might be a little tricky to read. If your IDE has a beautify or
prettify option, you can use it to make your code more readable like so:
var car = {
color: 'Yellow',
tires: 'Firestone',
horses: 300,
slow: false
};
To JavaScript, it’s the same thing. To us humans, the second version is more readable.
JavaScript Methods of Objects
Now that we know how to create objects easily, and give them properties, how can we
make them do things? Well, we can place function inside of objects as well. Let’s create
two different cars, and make a function that can provide information about the given object:
function carDetails(){
// display information about a car
console.log('This car is ' + this.color + ', has 4 ' +
this.tires + ' tires, and ' + this.horses + ' horespower')
}
var car1 = { color: 'Yellow', tires: 'Firestone', horses: 300, slow: false, info: carDetails }
var car2 = { color: 'Red', tires: 'Goodyear', horses: 400, slow: false, info: carDetails }
car1.info(); // This car is Yellow, has 4 Firestone tires, and 300 horespower
car2.info(); // This car is Red, has 4 Goodyear tires, and 400 horsepower
Note that we only had to define the carDetails() function once, yet it works on both of the
different objects! How does this happen? What is happening here is a the function is
making special use of the this keyword. this informs the program that we are dealing
with this particular instance of the object. This is how each object is able to associate the
correct data to it.
Node Types
Let’s take a look at a very simply example of HTML to show how and where these three
node types come into play:
<ul id="domtut">
<li>Search</li>
<li>Design</li>
<li></li>
</ul>
This is pretty interesting. What we have here is the HTML you can see when you open the
file or view the source code in a browser. The orange color items represent the actual
HTML, and any text inside the HTML. The color coded boxes are more representative of
the formal DOM structure. Black represents Element Nodes, Grey shows Attribute
Nodes, and Blue is what depicts Text Nodes. You see, a picture is worth a thousand
words!
Element Nodes Don’t Contain Text
This is an important point! You may be wondering, why go through all that trouble to show
how these nodes and elements are represented? Well, in contrast to what it looks like
when you view source HTML, Element Nodes do not Contain Text! It is only Text Nodes,
which are children of their parent Element Nodes that contain any actual text. We need to
understand this concept to effectively work with and modify the DOM as needed in our
JavaScript programs.
Get an Element by ID
When we have an element on the page, we can use the following very common and
possibly the most important method of the JavaScript language and that would be:
document.getElementById(‘someId’);
Often times the use case we’ll see with this method is by calling it, and assigning it’s result
to a variable. That variable then acts like a handle into that specific point in the DOM.
Think of it like opening a file, and this is the file handle so to speak. We can then use that
variable to call methods on that element, read properties of the element, or change that
element. This is not a copy of that element, we’ll be operating directly on that element
within the DOM once we start calling methods on it. For example:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Document Object Model Tutorial</title>
</head>
<body>
<ul id="domtut">
<li>Search</li>
<li>Design</li>
<li>Social</li>
<li></li>
<li></li>
</ul>
</body>
</html>
<script>
var dommer = document.getElementById('domtut');
console.log(dommer.nodeName); // UL
console.log(dommer.nodeType); // 1 (Element)
</script>
<body>
<ul id="domtut">
<li>Search</li>
<li>Design</li>
<li>Social</li>
<li></li>
<li></li>
</ul>
<ul id="lang">
<li>php</li>
<li>js</li>
</ul>
</body>
</html>
<script>
var langlis = document.getElementById('lang');
var restricted = langlis.getElementsByTagName('li')
console.log(restricted.length); // 2
console.log(restricted); // HTMLCollection[li, li]
console.log(restricted[0].innerHTML) // php
console.log(restricted[1].childNodes) // NodeList[<TextNode textContent="js">]
</script>
By having a command of the DOM, and what methods are available to operate on it, we
are able to get anywhere in the page we need to be.
Modifying Attributes
Starting with the easiest thing we could do, let’s modify an attribute of some example
HTML. We’ll be looking at two important methods for dealing with attributes.
someElement.getAttribute(‘class’);
someElement.setAttribute(‘id’, ‘newvalue’);
As ever, a demo is needed!
var someElement = document.getElementById('domtut');
console.log(someElement.getAttribute('id'));
someElement.setAttribute('id', 'newid');
console.log(someElement.getAttribute('id'));
This code fetches the ul that has an id of domtut, logs out the captured value, then makes
use of the setAttribute method to set a new id to that very element, and lastly logs out
the new value that has been modified. So there you have it, 4 simple lines of code to show
how to make use of the getAttribute and setAttribute methods.
Creating DOM Content
So let’s consider that in some of our prior example HTML, we did have some
empty li elements. Let’s see if we can populate and empty HTML element using only
JavaScript, I’m pretty sure we can do it! Recall we had 5 li elements in our domtut list. Only
the first 3 were populated, but we can populate the last 2 right from JavaScript. Check this
out:
var someElement = document.getElementsByTagName('li');
someElement[3].innerHTML = 'JavaScript made me!';
someElement[4].innerHTML = 'Me too son!';
Our updated HTML will now look like this with the last two list items now populated!
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Document Object Model Tutorial</title>
</head>
<body>
<ul id="domtut">
<li>Search</li>
<li>Design</li>
<li>Social</li>
<li>JavaScript made me!</li>
<li>Me too son!</li>
</ul>
<ul id="lang">
<li>php</li>
<li>js</li>
</ul>
</body>
</html>
Creating Elements
We also have the ability to create elements and nodes on the fly, and populate as
required. You probably wouldn’t want to do this, but you could construct an entire webpage
using nothing but JavaScript! We are going to add another li element to our HTML and
populate it as needed. First we’ll need to make use of a new method.
document.createElement(‘li’);
This is pretty cool, an li will be created into the world. Actually, it is created into the DOM,
but our new li feels lost. He has no place in the world. We need to help him find where he
should be. We can do this by making use of another new method.
someElement.appendChild(‘newlyCreated’);
So now that we have our newly created element, it must be appended somewhere into the
DOM. This is how things would look so far:
var newlyCreated = document.createElement('li');
var someElement = document.getElementById('domtut');
someElement.appendChild(newlyCreated);
If you run this snippet in firebug, you will see a new li item get added to that first list. In fact,
start clicking run like a mad man and watch those li items keep getting generated and
appended into the page like crazy! Don’t worry, once you have fun doing this, you can just
refresh the browser and everything will be back to normal This is a great example
though of how to dynamically create, and then append items on the fly. Cool!
So yes, just setting the innerHTML property of the element may be a little quicker, but the
second method of creating the text node and appending it in the DOM is the more formal
and precise way to accomplish this.
Alternatives to appendChild
You may be up to your eyeballs in the DOM at this point, but there is one more thing we
need to cover! We can insert elements into the DOM in more ways than one. Here is an
alternate way to accomplish the same thing.
var theParent = document.getElementById('domtut');
var newLi = document.createElement('li');
var insertPoint = theParent.getElementsByTagName('li')[0];
theParent.insertBefore(newLi,insertPoint);
Whoa Nelly! What the heck is going on here? Let’s talk it through, as this helps to
understand better.
And with that friends, you have completed the Vegibit Crash Course on the Document
Object Model! Congratulations
We’re getting a good foundation on what JavaScript is all about so far with our
study of the basic syntax, types, objects, and the Document Object Model.
Where things start to get more interesting is when we begin to work with
events. JavaScript is perfectly suited for dealing with an event driven style of
programming. Learning How to Use jQuery Event Handling is also a great
approach to dealing with JavaScript events – but it is important to know the
underlying technology. With this approach, we can do amazing things with
JavaScript, so let’s jump right in!
Events and Listeners
Having the ability to react to what the user is doing is one of the main benefits of events
and listeners. Maybe we want to take an action when a user clicks a certain link, or fills out
a particular form field, or simply moves their mouse to a different location. All of these
things are triggering events on the user’s behalf, and we can write code to handle them.
What is an Event?
JavaScript events are actions that happen on their own. The events are happening all the
time, JavaScript simply listens for the ones you specify, and then you can take some
action. For example all of the following are events
It is you, the programmer, that will decide which ones you want to take action on. The
events are built right into JavaScript and there are keywords that describe them. They are
lowercase and usually start with on. For example, these are all JavaScript events:
• onload
• onclick
• onmouseover
• onblur
• onfocus
We as programmers do not write the event itself, we write the event handler. Basically, we
write a JavaScript function, which is the event handler, and this function will handle an
event when it happens.
Here are three different ways to respond to events in JavaScript.
Inline JavaScript
I would not recommend using this approach, but it does exist so we’ll talk about it for the
sake of completeness. Just like you can place CSS inline in your HTML, so to can you
place JavaScript inline. As you probably are well aware, it is always best to place your
CSS in it’s own file, and JavaScript is no different. Let’s look at how to do something inline
though, just to check it out.
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>What Are JavaScript Events</title>
</head>
<body>
<ul id="domtut">
<li><a href="#" onclick="alert('What can I say? Alert Boxes are GREAT for tutorials!');">Click It
or Ticket!</a></li>
</ul>
</body>
</html>
Here we simply give our a tag an onclick event handler, and yes, we simply run an alert
box to prove it’s doing something.
Element dot Event Syntax
The second way to handle events is to use the syntax of specifying the element, then
using the dot .operator syntax to choose an event. There are many free IDEs or Integrated
Development Editors that can help you with auto complete tips for using this. For example,
in this snippet we use the very slick Adobe Brackets to help us with auto complete. As
soon as we begin typing the name of the element, then type the dot, a list of available
options will become available to you like so:
So now, we are moving our script out to it’s own file named, tut.js. Here is how we include
it in the HTML:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>What Are JavaScript Events</title>
</head>
<body>
<ul id="domtut">
<li>
<a id="smiley" href="#">The Second Method!</a>
</li>
</ul>
<script src="tut.js">
</script>
</body>
</html>
Now that we have this in play, we can put some actual script in the script file just like this:
var a = document.getElementById('smiley');
a.onclick = function () {
console.log('Oh yeah, you KNOW I just clicked that link!');
}
Excellent!Here we simply grab the element we are interested in, that would be the a tag, and
assign it to a variable named a. Now we simply assign an anonymous function to
the onclick event of that element. This anonymous function is the event handler which
will only run when a user clicks the element. This is a much more common way to do
things in JavaScript. If the idea of an anonymous function being assigned to an event or
variable is new to you, don’t worry, we will be covering function in JavaScript in depth
soon!
Add Event Listener
The third way to handle events is by using a special method which adds a listener to the
document or element you are interested in. Let’s rewrite the prior example and use this
style instead.
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>What Are JavaScript Events</title>
</head>
<body>
<ul id="domtut">
<li>
<a id="smiley" href="#">The Third Method!</a>
</li>
</ul>
<script src="tut.js">
</script>
</body>
</html>
var a = document.getElementById('smiley');
funcone = function () {
console.log('Oh yeah, you KNOW I just clicked that link!');
}
functwo = function () {
console.log('Two actions firing, yeah whats up now?!');
}
When we run the code by clicking our link, we can see some interesting things happen!
This brings us to a small discussion on the pros and cons of using this approach. As you
noticed, we actually fired two actions based on the one click event. So this is quite a
flexible thing. We can set up many listeners for just one event. It doesn’t necessarily have
to be a click event either. With this added benefit though is also a drawback. The drawback
here is that Internet Explorer version 8 and prior use a different method all together to
accomplish this goal. Their method of doing this uses attachEvent('click',
somefunc); This is easily solved by using a cross browser compatible library like jQuery for
<head>
<meta charset="utf-8">
<title>What Are JavaScript Events</title>
<script src="tut.js">
</script>
</head>
<body>
<ul id="domtut">
<li>
<img src="/bootstrap/img/panda.png">
</li>
</ul>
</body>
</html>
document.onclick = function () {
console.log('You have clicked the document');
}
Upon loading this script up in the browser and clicking anywhere in the document, we see
the logging correctly triggering. This is just a simple example to show that *any* element
can handle the click event, not just a link, button, or image. The document is also an
element, and by following the convention element.event we can do whatever we like in the
page.
Clicking on the document is great, but it’s kind of like using a whale net to capture a
minnow. In other words, it’s not all that useful. In real applications we’re going to need to
respond to very specific click events. Since everything on the page is an element in the
DOM, and accessing a JavaScript event follows the element.event convention, we can
respond to a click on *anything* in the page. Let’s set up an example of clicking the Panda
Image.
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>What Are JavaScript Events</title>
<script src="tut.js">
</script>
</head>
<body>
<ul id="domtut">
<li>
<img id="pandalove" src="/bootstrap/img/panda.png">
</li>
</ul>
</body>
</html>
document.onclick = function () {
console.log('You have clicked the document');
}
panda.onclick = function () {
console.log('It is fun to click the Panda');
}
Loading this up in the browser and clicking the Panda gives us some strange results. If we
click it, we’ll get the same exact response as the screenshot from the first example. Why is
this not working? Notice in the HTML that we moved the script up into the head of the page
rather than right before the closing body tag. Also remember that when websites load in a
browser, everything is read from the top down and executed in the order in which it was
read, including JavaScript. The problem in this example is that the JavaScript is executing
before the Panda Image has even loaded on the page. It’s going to be hard to respond to a
click on an element that does not yet exist! This leads to an important concept and rule to
follow when dealing with JavaScript. It is important that all elements of the page have been
loaded, which means that the DOM if fully in tact and in place, before any JavaScript
executes. This is a common problem with a simple solution.
onload
The window object is the top level object in JavaScript. Even though we’ve been talking a
lot about the document object, it is the window object that sits at the very pinnacle of the
DOM. Because of this it is the window.onload event that tells us when the DOM has
finished loading and is ready to go. We can make just a small modification to our
JavaScript example, and everything will now work. Observe.
window.onload = function () {
document.onclick = function () {
console.log('You have clicked the document');
}
panda.onclick = function () {
console.log('It is fun to click the Panda');
}
}
So what is going on here? We did not change the order in which the information gets read
into the browser as the page loads. In fact, The browser is still hitting the JavaScript in
question before the Panda Image loads. If we test this in the browser though, things are
working.
The answer lies in the fact that we wrapped our existing JavaScript code within
the window.onloadevent. Let’s talk it through. The web page begins loading and again
comes across the JavaScript file first, before the Panda Image loads. Now, here is the
difference: In the prior example, things started executing right as soon as the statements in
the code were hit. Specifically, when this line of code tries to run
panda.onclick = function () {
console.log('It is fun to click the Panda');
}
panda has a null value, so the code fails. In our new example, all of the JavaScript is
inside the block:
window.onload = function () {
// code now here
}
When the JavaScript engine hits this line, it knows to read this as so. Do not execute any
code inside this block until the webpage has been fully loaded. It is this line of code that
tells us when the DOM is ready. In plain English, we can read it as, “When the web page is
ready, execute this code”. And that is exactly what it does, and all is well!
onfocus and onblur
The onfocus and onblur events are used all the time in form processing. Let’s say we
have an input field that is part of our webpage. We’d like users to be able to submit
feedback about their thoughts on the Panda. It would be nice to add some interactivity to
the input to prompt the user to enter some information, and clear the text when the user
clicks in the field and is ready to type. Here is the markup and code to make that happen.
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>What Are JavaScript Events</title>
<script src="tut.js">
</script>
</head>
<body>
<ul id="domtut">
<li>
<img id="pandalove" src="/bootstrap/img/panda.png">
</li>
<li>
<form>
<input size="70" type="text" value="Do you like the Panda? Click here to tell us!" id="text" />
<input type="submit" value="submit" />
</form>
</li>
</ul>
</body>
</html>
window.onload = function () {
var textarea = document.getElementById('text');
textarea.onfocus = function () {
if (textarea.value == 'Do you like the Panda? Click here to tell us!') {
textarea.value = '';
}
}
textarea.onblur = function () {
if (textarea.value == '') {
textarea.value = 'Do you like the Panda? Click here to tell us!';
}
}
}
We can click in the input field and add our thoughts. When doing this, the default text will
automatically clear.
Again, in talking it through, it will make all the sense in the world. The web page loads, and
when the input field is encountered in the page, it is populated with the text, “Do you like
the Panda? Click here to tell us!” This gives our users a good indication of what we would
like them to do with this text input! Now, we have some JavaScript code that will run when
the page is ready, as we did keep our logic inside of the window.onload event here. When
this code runs, it checks to see when the user clicks inside of our input by making use of
the onfocus event. onfocus tells us when a form field currently has focus, or when the
user has clicked inside of it. When the user clicks this the field, focus is given, and at that
time we check to see if the value of that element is equal to our default text. It is, so then,
we instruct JavaScript to set this text to an empty string. This provides the action of
clearing out our given text, and allows the user to type their own feedback. The next thing
to happen is that we check to see if the user clicks away from this field using
the onblur event. onblur tells us when the user has clicked somewhere else on the page,
leaving the currently in focus element. The JavaScript then checks to see if the value of
that element is an empty string. This condition would be true if the user clicked away and
left a blank input. In that case, we want to remind them that hey, we want to know what
you think about these Pandas friend. So what we will do, is that if the value is empty, we
will re set that value right back to “Do you like the Panda? Click here to tell us!” This way,
we are nudging the user in the right direction as to the call to action on the page. Pretty
cool, right?!
JavaScript Timers
While not officially a JavaScript event, times are really incredible feature of the language.
They do have a bit of an event-like feel to them, so why not cover what we can do with
timers as well, right? Timers are used all the time for things like slideshows, clocks, or any
other instance where we need an action to take place after a set period of time or several
times over the course of time.
setTimeout
The setTimeout() function takes two arguments. The first is the function, or action to take.
The second is the amount of time to wait before executing the given function. This value is
provided in milliseconds. So for example, if we want something to happen after a 3 second
time frame, we pass in 3000. We use setTimeout when we want an action to take place,
but only after a specified time. Here is some example code to show setTimeout in action:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>What Are JavaScript Events</title>
<script src="tut.js">
</script>
</head>
<body>
<div id="one"></div>
<div id="two"></div>
<div id="three"></div>
<div id="four"></div>
<div id="five"></div>
<div id="six"></div>
</body>
</html>
window.onload = function () {
var one = function () {
var h6 = document.createElement('h6');
var one = document.getElementById('one');
one.appendChild(h6).innerHTML = 'This';
};
setTimeout(one, 504);
setTimeout(two, 720);
setTimeout(three, 1029);
setTimeout(four, 1470);
setTimeout(five, 2100);
setTimeout(six, 3000);
}
This is a pretty cool example, considering we could have simply just ran an alert to the
page after 4 seconds Instead, what we do here is populate 6 different div elements
with a message. Each setTimeout event handles one part of the message, This is an
example of Timers in JavaScript!
setInterval
The setInterval function is like a setTimeout on replay. If you have an action that you want
to take place repeatedly at set intervals, you use this function. As always, we’ll provide a
fun example:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>What Are JavaScript Events</title>
<script src="tut.js">
</script>
</head>
<body>
<h1 id="message"></h1>
</body>
</html>
window.onload = function () {
setInterval(welike, 500);
Here is the idea of what is happening in this example. We have a very simple h1 element
on the HTML page. The JavaScript is slightly more involved. Let’s bullet point it.
When you load this in the Browser, you will witness an h1 tag which has text that changes
between JavaScript, PHP, CSS, and HTML5 every 500 milliseconds.
clearInterval
Ok, you’ve set a bunch of words spinning about on the webpage every 500 milliseconds.
Yes, it will not take long for this to start to drive you bananas. Before you scream, “Make it
stop!” be comforted, we can write some JavaScript using the clearInterval function to bring
your sanity back! Here is the updated HTML and JavaScript to give us a Start and Stop
button to start and stop the welike() function in real time, it’s quite slick!
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>What Are JavaScript Events</title>
<script src="tut.js">
</script>
</head>
<body>
<h1 id="message"></h1>
<table width="500">
<tr>
<td>
<input type="submit" name="start" id="start" value="Start">
</td>
<td>
<input type="submit" name="stop" id="stop" value="Stop">
</td>
</tr>
</table>
</body>
</html>
window.onload = function () {
function welike() {
div.innerHTML = message[messageIndex];
messageIndex++;
if (messageIndex >= message.length) {
messageIndex = 0;
}
}
start.onclick = function () {
stop.onclick = function () {
clearInterval(stopstart);
}
}
How does clearInterval work? In this JavaScript snippet we do not simply make a call
to setIntervalpassing in the welike function and 500 milliseconds. We first set up onclick
event handlers for two new buttons on the HTML page. When the user clicks the Start
Button, an anonymous function runs. Inside of the anonymous function is where we trigger
that setInterval function. When clicked, this sets the welike function in motion once every
500 milliseconds. You’ll note that we also assigned a return value to the
variable stopstart when setInterval was called. What this does is basically give us a
handle into the setInterval process for this particular instance. We can pass this handle
into the clearInterval function and it knows that this is instructing that instance
of setInterval to stop. This is awesome stuff folks.
JavaScript Functions are arguably the most important part of the language. As
you begin to study them more deeply, you realize there is a lot more to them
than meets the eye. This JavaScript series is really about covering the
JavaScript Fundamentals, in order to build a solid understanding of JavaScript
before we move into awesome JavaScript frameworks like jQuery and Node.js.
If you are a student of Douglas Crockford, you’ll know it is in his opinion that
JavaScript will be the language to rule them all, from Browser to Server, and
back again. While that remains to be seen, JavaScript is here, it is widely used,
and it provides many benefits, so we will need to get our hands dirty with it!
What is a JavaScript Function?
As we write more and more statements in our code, we need to take steps to keep things
organized. To avoid things getting messy and disorganized, we can break apart large
pieces of JavaScript into smaller, reusable blocks of code. As you know, all programming
languages have this ability and JavaScript is no different.
Named Functions
The first way to create a function is to use the named approach.
function learn () {
var brain = 'Web Development Best Practices';
console.log(brain);
}
learn();
In this example, we simply declare a function called learn, set a variable with the string Web
Development Best Practices, then simply log that variable to the console. Go ahead, try it
in Firebug now!
function learn () {
var brain = 'Web Development Best Practices';
console.log(brain);
}
This however is not a best practice. JavaScript likes to try and make things easy for you in
different ways. One of them is by scanning your JavaScript first, before actually calling any
functions. So yes, you could call a function before it is officially declared but this will only
add to confusion when you or members of your team need to read the code at a later time.
So be the good chap that you are, and define your functions first, then call them later
doubleIt(5); // 10
doubleIt(25); // 50
doubleIt(555); // 1110
In this example we simple name a function called doubleIt which takes just one
parameter, multiplies that number by 2, and logs the result. When we call the function
passing in various number values, they do get correctly doubled.
Returning a Value
Most times, functions return a value. Almost all functions built into the language return
some type of value, and when we write our own functions, we are probably going to want
to return a value as well. We can return at any point in the function based on some logic,
or we may simply want to do some calculations, and when we are finished return that
result. Our example rewritten using a return statement would look like this:
function doubleIt ( number ) {
var result = number * 2;
return result;
};
In this example, we have a nifty little function that accepts 4 parameters and calculates a
mortgage for us. When it is called on the three following lines, we show an example of
correct number of parameters, too many parameters, and too few parameters. Each
instance has different behavior.
In JavaScript:
Again, this is useful inasmuch as your code will not fail to run – but you need to pay
attention, as most times you will want to actually pass the correct number of parameters to
any given function.
Function Scope
In JavaScript there is no block scope, but there is function scope. What this means is that
variables defined inside of a function, are only available for use inside that function.
local variable
function doubleIt ( number ) {
var result = number * 2; // result is a local variable only
console.log(result); // result is 4 inside the function
};
doubleIt(2);
console.log(result); // result is undefined outside the function
global variable
The alternative to a local variable in a function is a global variable. Just be careful, it is
thought that Douglas Crockford rains fire upon kittens each time a global variable is used
in JavaScript. You still need to know how to use one however, and this is how you do it:
var result;
doubleIt(2);
console.log(result); // result is 4 outside the function as well
By declaring the variable result outside of the function, it is visible throughout the entire
program. That is to say, it is a global variable.
Here, we assign an anonymous function to the variable hi. We can then use hi like a
function! Where we will see anonymous functions in a more real world situation is in the
modern JavaScript frameworks. Here we will often see functions get passed as arguments
to other functions, and this is where the real fun begins.
Here is a super simple example to show passing a function as an argument to the
JavaScript built in setTimeout() function.
setTimeout(function() {
var mes = 'I will log to the console after 2 seconds';
console.log(mes);
}, 2000);
When we run this script, it does exactly what it says it will do. It will wait for 2 seconds, and
then log a message to the console. Use your imagination, think of all the incredible things
you can do with this type of construct. It comes in very handy quite often.
Now the syntax is a little tricky if this is the first time you have seen it. Let’s look at it
another way.
setTimeout(function() {var mes = ‘I will log to the console after 2 seconds’;
console.log(mes); },2000);
This is simply setTimeout( arg1, arg2 ); with arg1 in italics and arg2 bolded. Hopefully
that drives the idea home.
Anonymous Functions as Event Handlers
We recently covered JavaScript Events and how we can respond to those events. Well
you guessed it, the anonymous function is the main way we can respond to events
happening in JavaScript! Here’s a fun one. Let’s respond to the mouse movements of the
user and take some action on every mouse move just for fun:
document.onmousemove = function () {
console.log('running');
};
Ha! You can see, after making a few circles on the screen for a few seconds, our little event
handler logged one thousand, two hundred and eighty one messages to the console!!
Sure, it’s a funny example, but it shows the idea of how anonymous functions can respond
to events in JavaScript.
Closures In JavaScript
Last up, we have a quick mention of Closures in JavaScript. Moving forward, we’ll
dedicate a whole tutorial to just Closures in JavaScript, since it is an important concept in
the language. For this example though, we just want to get the general idea of what a
closure means.
We can have functions inside of other functions. Recall we said that in JavaScript, we have
function scope. This means a variable inside a function is only visible in that function. So
what happens when you have a function inside of a function? This is
where closure comes into play.
(function two () {
console.log(num1);
console.log(num2);
})();
In the above example notice that we have a function named one, then inside of that
function there is another function named two. Notice that function one accepts two
parameters, and function two accepts no parameters. Also notice that function two is a self
executing anonymous function. After this is all declared, we call the function one and pass
in the numbers 5 and 10. Technically, function one doesn’t even do anything with these
variables. When function one runs, inside of the body of that function, function two is going
to execute. function two then writes out the variables passed in to function one to the
console. What?! Function two doesn’t even take any parameters, how the heck is it able to
write out the correct values? It is able to do this through closure, the inner function has
access to the context of the outer function.
var day = (function () {
}());
theday = day(4);
console.log(theday); // thurs
In this second example, we do something a little more complex. The example is inspired
by the teachings of Douglas Crockford, and it is a bit of a mind bender, but once you get it,
it helps cement the concept of closure in your brain. So what is happening in this code?
Let’s observe just the outer function for the moment.
Now, let’s move on to this line theday = day(4);. There is a function in day. You would
think it is the outer function assigned to day, since as we see in the first line var day =
(function () {, there is an assignment operator = with a variable on the left, and a
function on the right. Well, it must be that function in there, right? Wrong! Since the outer
function executes immediately, it simply sets up the days array,
and returns the function defined within it. This outer function is now done and complete.
At this point, the inner anonymous function which takes a number as a parameter is what
is stored in day! Now, that inner function runs, and we pass in a number, in this case 4 as
an index. Remember, the outer function has already returned, so it’s variables should also
be gone and no longer in existence – at least this is what you would expect. In reality
however, this outer variable days, is still available to that inner function at this later point in
time due to closure.
jQuery is the most popular open source JavaScript Library in the world. It
simplifies the task of making highly responsive web pages that work across all
of the modern web browsers. jQuery makes common scripting tasks much
easier by providing a short and easy to understand syntax. Instead of having to
access the DOM directly, jQuery provides a much easier way to access, modify,
and update the DOM as you see fit. jQuery is used everywhere, and we need to
be fluent in it as well so lets jump right in to jQuery!
jQuery Overview
jQuery breaks down into several categories of functionality. They are listed as follows:
• Core Functionality Provides the core features of the library as well as many helpful
utility methods.
• Selection and Traversal This provides the common functions for finding what you
want inside of HTML documents, as well as the traversal of those documents.
• Manipulation and CSS Functions in this category allow for editing and changing the
content within the document as well as manipulating CSS.
• Events jQuery provides a powerful unified event object that simplifies working with
events and cross browser event related problems.
• Effects As you have surely seen on the web, jQuery is the library that can provide
animations, hiding and showing of content, as well as moving elements on the page.
• Ajax One of the most powerful aspects of the library is its excellent implementation
of AJAX and the related helper methods that come along with this.
• jQuery selectors return an array of objects based on the criteria given for the
selector.
• jQuery filters on the other hand, refine the results contained in the returned array.
The returned array is not a set of DOM elements. What gets returned are actually jQuery
objects, or DOM elements wrapped within jQuery objects. It is this wrapping that provides
all of the methods and properties that jQuery has to offer so you can operate on those
selected objects. This is often called the wrapped set.
.className select all elements that have a class attribute set to className
tag.className select all elements for the provided tag which have a class attribute set to className
tag#wow.className select all elements that have an ID set to wow and a class set to className
<body class="container">
<ul id="funlist">
<li class="markup">HTML5</li>
<li class="presentation">CSS3</li>
<li class="behavior">JavaScript</li>
<li class="framework class1 class2">jQuery</li>
</ul>
<p class="markup">HTML5 is a markup language used for structuring and presenting content for the
World Wide Web and a core technology of the Internet.</p>
<p class="presentation">Cascading Style Sheets (CSS) is a style sheet language used for describing
the look and formatting of a document written in a markup language.</p>
<p class="behavior">JavaScript (JS) is a dynamic computer programming language.</p>
<p class="framework">jQuery is a cross-platform JavaScript library designed to simplify the client-
side scripting of HTML.</p>
<!-- jQuery 1.11.1(latest non minified) -->
<script src="jquery-1.11.1.js"></script>
<!-- Include all compiled plugins (below), or include individual files as needed -->
<script src="bootstrap/js/bootstrap.js"></script>
<!-- custom written js -->
<script src="tut.js"></script>
</body>
</html>
Combination
.class1.class2 get all elements that have both class1 and class2
Hierarchy
parent > child get all child elements that are direct children of elements of type parent
ancestor descendant get all descendant elements that are within elements of the ancestor type
Siblings
prev + next get all next elements that are next to a prev element
prev ~ siblings get all sibling elements that are after prev and match the siblings selector
These are a little more tricky so let’s take a look at some examples. You’ll see in the
example HTML provided that we also included a copy of Twitter Bootstrap in the page.
This way, we can make use of the jQuery .addClass() method and simply add a class to
our selected elements. The traditional tutorial might use the jQuery .css() method and
pass in some CSS values, and this is a perfectly good way to show selecting elements as
well. We’ll load up the HTML in a web browser and run the following commands in firebug
to see what happens. For the entirety of this post, we can focus on the initial part of the
expression, meaning, anything that comes before .addClass().
$('ul > li.markup').addClass('alert alert-info'); // parent > child
$('ul li.presentation').addClass('alert alert-success'); // ancestor descendant
$('li.behavior').addClass('alert alert-warning'); // tag.class
$('.class1.class2').addClass('alert alert-info'); // .class1.class2
$('#funlist + p').addClass('alert alert-success'); // prev + next
$('p.behavior ~ p').addClass('alert alert-warning'); // prev ~ siblings
By loading up our jQuery enabled page in firefox with firebug running, we
This is pretty cool!
can simply type some simple jQuery into the console of firebug and trigger off page
updates in real time. You don’t have to stop there, refresh your browser to clear the styling,
and click the clear button in the firebug console to clear out your sample jQuery. Now you
can go crazy testing any combination of selectors you can think of! You should do just that
as well – by practicing all of the different combinations of selectors on your markup, you’ll
quickly become familiar with how these selectors work and after a while they will become
second nature to you.
• Basic Basic filters allow you to filter the first, last, even, or odd numbered items from
the wrapped set.
• Content Content filters provide the ability to filter elements based on the content
such as an element containing a given string.
• Visibility Filters the set of elements by looking at the visibility setting of each
element.
• Attribute Looks at a provided attribute an an element to filter out or not.
• Child Gets elements depending on their relationship with their parent element.
• Form Gives filters to specifically operate on form elements in the page.
Here are some of the most commonly used filters. In looking at them, we can see how they
are essentially CSS selectors, and they work much the same. The syntax is very similar.
:header Selects all header elements like h1, h2, h3, h4…
So where would you use filters? Well consider a scenario where there are a lot of elements
on the page, and maybe there are not a lot of unique ID’s in use or class names for that
matter. In selecting data, we need some way to identify it. If we are unable to narrow things
down with basic selectors, we then start using filters to refine things. Let’s see some of
these filters in action operating on the same HTML we used for the selectors examples.
$('li:first').addClass('alert alert-info'); // :first
$('li:eq(1)').addClass('alert alert-success'); // :eq(n)
$('li:eq(2)').addClass('alert alert-warning'); // :eq(n)
$('li:last').addClass('alert alert-info'); // :last
$('p:even').addClass('alert alert-warning'); // :even
In fact as we use jQuery, just like in native JavaScript or another programming language,
there are often several paths to the final destination. You can solve the same problem with
many different approaches. How you solve that problem is a matter of preference and
style, and we know you are one stylish person!
jQuery Attribute Filters
In addition to the positional and index based filters we mentioned so far, jQuery also
provides a great set of attribute filters. What this does is allow us to filter the results of a
selector statement based on the content of an attribute. Here are the attribute filters to
know.
[attribute] Includes elements in the result set if they have the given attribute
[attribute=value] Includes elements in the result set only if they have the given attribute and a specific value
[attribute!=value] Includes elements in the result set only if they have the given attribute and it is not a specific valu
[attribute^=value] Includes elements in the result set only if they have the given attribute and it starts with the given
[attribute$=value] Includes elements in the result set only if they have the given attribute and it ends with the given
[attribute*=value] Includes elements in the result set only if they have the given attribute and it contains a specific v
[attr1][attr2] Includes elements in the result set only if they match all given attribute filters
Making use of the different types of attribute filters, we can see how they behave. Attribute
filters come in really handy quite often.
$('li[class=markup]').addClass('alert alert-info');
$('li[class=presentation]').addClass('alert alert-success');
$('li[class=behavior]').addClass('alert alert-warning');
$('li[class^=frame]').addClass('alert alert-info');
$('p[class^=f][class$=k]').addClass('alert alert-warning');
jQuery Content and Visibility Filters
Moving on in our study of filters in jQuery, we now will take a look at content and visibility
filters. You may have thought there were no additional filters to need, but alas, jQuery
gives you virtually limitless options when it comes to selecting and filtering data.
:contains(text) Filters the selection to include elements that contain text string
:empty Filters the selection to only include elements that are empty
:has(selector) Will match elements that contain at least one element which has the given selector
:parent Matches all elements that have at least one child element
:nth-child(index) Matches elements at the index, even, odd, or that match an equaltion in the form of Xn + M
:nth-child(even)
:nth-child(odd)
:nth-child(equation)
:first-child Matches elements that are the first child of their parent element
:last-child Matches elements that are the last child of their parent element
:only-child Matches elements that are the only child of their parent element
As with the other examples, simply think of creative ways to test these filters in the browser
using firebug and some test HTML. Practice makes Perfect!
Conclusion
This completes the study of jQuery selectors and filters for this tutorial. It may seem a bit
long, but in reality, when we are using jQuery as we have stated earlier on, the very first
thing you do in jQuery is to select content from the page to operate on. It makes sense to
have your selectors and filters down cold, since if you have the right data to work with to
begin with, your applications will be that much easier to build and debug. Take some time
to test these out. It’s as easy as opening the firebug console and typing some example
selector and filter statements in!
size() or length Provides the total number of elements in the wrapped set
get() Returns the actual DOM elements rather than jQuery wrapped objects
Let’t talk about the use cases for each of the methods listed above. The first one is
the size() method. When doing selections on the DOM with jQuery, it is often useful to
find out how many objects were returned in the wrapped set. You may want to check the
number of links on a given page. With this method, you can find that information out. In
fact this simple snippet will tell you just that. $('a').size(); Other times your code may
simply need to check if objects were returned or not and what steps may or may not come
next based on this result. Again this method is what you would use that for. In addition to
this method, you could simply use the length property as it provides the same exact
information. In fact, when I’m reading data, this feels a bit more natural, $('a').length;
The get() and get(index) methods are used to get access directly to the DOM elements
themselves. Remember, when we are doing selections in jQuery, what gets returned to us
are the DOM elements that are wrapped inside a jQuery object. This is why it is typically
referred to as the wrapped set. This is how those returned objects are able to have access
to the many convenient methods that the jQuery library provides. If there is a use case
where you simply just want to operate on actual native DOM elements themselves using
native JavaScript, then this is when you can use get() or get(index) to accomplish this
goal.
find() is used to search inside a matched element to find another element based on the
expression provided to the method.
each() is great since it allows you to easily loop over the contents of the wrapped set and
perform actions on them via functions. Most popular jQuery plugins use this method
frequently.
Let’s whip up an example of using the each() method on our returned set. Here is the
code, and we’ll just run it in firebug to keep it simple. You can follow along if you like.
var i = 0;
var theme = ['alert alert-info',
'alert alert-success',
'alert alert-warning',
'alert alert-info']
$('p').each(function() {
$(this).addClass(theme[i]);
i++;
});
Cool! So how does this work? What happens here is first, we set a counter in the variable i.
The next thing to do is to set up a theme array, and populate it with four different classes
that we are going to use in the function that runs in our each() method. Now, we select all
of the paragraph elements on the page and apply the each() method to the result. They
way each() works is you specify an anonymous function inside of the each() method, or in
other words, we pass an anonymous function to the each() method. Now, each() is going
to loop over all of the elements in our wrapped set. In this case we have four paragraphs
so what happens is, starting with the first iteration, we use the .addClass() method on the
first element to assign a specific class name. How does this happen? It looks a little
different than your typical loop structure than you may be used to. $(this) actually
changes on each iteration. The first time through, it is referencing the first paragraph in
our wrapped set. The second time through, it is referencing the second paragraph in our
wrapped set, and so on. Since $(this) is a jQuery object, and *not* a raw DOM Element,
we can enjoy access to any method jQuery makes available to us. In this case, we’re using
the .addClass() method, but it could just as easily be any number of other methods in the
jQuery library. On iteration one, $(this) is paragraph one, and i is at index 0. Therefore,
when we run the .addClass() method on $(this), it applies the class of alert alert-
info to this paragraph since that is the class that lives at index 0 of the themearray. On the
next iteration, we are dealing with paragraph two. This time, the counter has been
incremented so when we add the class, it is now alert alert-success that gets applied
since that is the class that lives at index 1 of the theme array. This continues until all
elements have been looped over. This is how we can make use of the .each() method,
awesome!
$(selector).fn1().fn2().fn3();
The .fn1().fn2().fn3(); portion is the statement chain in this example. So what’s the big
deal you ask? Well, if you return a bunch of elements with your selector, you can then
apply a function to all of them and once complete apply another, and then another, all in a
very compact style of syntax. It is worth noting that some of the JavaScript Gurus have
expressed their opinions that this style may have been taken to an extreme in recent
years, but it is still a useful tool in your jQuery toolkit. For a bit of a non sensical example,
let’s look at the following code:
$('p:last').addClass('alert alert-info').slideUp('slow', function(){
$(this).removeClass('alert alert-info').addClass('alert alert-success');
}
).slideDown('slow').fadeOut('slow', function() {
$(this).removeClass('alert alert-success').addClass('alert alert-warning');
}
).fadeIn('slow');
This introduces the concept of callbacks in jQuery in addition to the method chaining we
are using. Notice in the code that we use the selector only once in the whole expression.
We only reference the last paragraph on the page by using the $('p:last') selector. From
there, it is simply a matter of applying different methods to that element in succession.
Talking through the example helps to drive the point home. First, we grab the last
paragraph element on the page. Then the alert alert-infoclass is added to the element
via the .addClass() method. Now comes the first additional method that makes up
our statement chain, .slideUp(). The .slideUp() method takes two arguments, and one
is a callback so it is worth explaining. The first argument simply tells
the .slideUp() method at what speed we would like the effect to happen at. In our case,
we make it slow. The second option is a callback function, and it is really cool how this
works. Since we can pass a function as an argument to another function in JavaScript, it
makes these types of callbacks possible. The way the callback works is first, it waits for the
function it is being passed to, to finish it’s execution. Once it is complete, the callback
function will run. This is why when the paragraph slides up, it retains it’s original class and
color until it has finished sliding. Once it stops, the anonymous callback function runs and
triggers two things to happen. In true jQuery style, we are actually embedding a statement
chain within a statement chain here! When the anonymous function runs, this line of code
gets triggered:
$(this).removeClass('alert alert-info').addClass('alert alert-success');
Here, $(this) refers to the paragraph element that we originally captured. This is
excellent, since we do not have to go through the overhead of selecting that element yet
again. Using this convention, we can reduce the number of times we have to actually
query the document, and just work with our elements as long as need be until they have
reached the state we desire.
So what this line says is, “take that original paragraph element we have, remove the class
we had assigned to it, the add a different class to it“. Very slick.
After that we add to the original statement chain by running the .slideDown() method, then
the .fadeOut() method which also takes a callback function. Finally we run the
final .fadeIn() method to finish the statement chain. This shows us two things, first that
statement chaining is really cool and useful, and two, that you can see where people might
take this style to an extreme, so certainly use this approach but keep it within reason.
Once you have this small collection of methods mastered, visit the offical docs to learn
about some additional traversing methods you might find useful.
As we move forward in learning bigger and better things about jQuery, we find
the need to go beyond just using selectors to grab the content we want. The
large number of selectors and filters available to us are a lot to learn, but once
we are fluent with them, we can then start using other jQuery methods to
manipulate the content in the DOM. We can create, remove, change, add,
animate, or do pretty much whatever we want with that content. Let’s start
testing this out now!
html() or length Returns the actual HTML of the first element matched
The general idea with these methods is that if you do not provide any arguments to them,
whether HTML or text, they will go out and fetch what is in the matched elements. If
you do provide HTML or text as an argument to these methods, then they will insert this
content into whatever your selector matches. Quite intuitive!
Here is an example of using a few of these different methods using the following code.
var rawhtml = $('ul').html(); // get raw html using .html()
$('#output > b').text(rawhtml); // pass raw html to .text()
var newhtml = $('<h4><em>The program has run.</em></h4>'); // create new html element
$('#output2').html(newhtml); // insert new html with .html()
$('#output3').text('and that was fun!'); // insert text
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>jQuery</title>
<link rel="stylesheet" href="bootstrap/css/bootstrap.css">
</head>
<body class="container">
<ul id="funlist">
<li class="markup">HTML5</li>
<li class="presentation">CSS3</li>
<li class="behavior">JavaScript</li>
<li class="framework class1 class2">jQuery</li>
</ul>
<p class="markup">HTML5 is a markup language used for structuring and presenting content for the
World Wide Web and a core technology of the Internet.</p>
<p class="presentation">Cascading Style Sheets (CSS) is a style sheet language used for describing
the look and formatting of a document written in a markup language.</p>
<p class="behavior">JavaScript (JS) is a dynamic computer programming language.</p>
<p class="framework">jQuery is a cross-platform JavaScript library designed to simplify the client-
side scripting of HTML.</p>
<div id="output2"></div>
<div id="output3"></div>
attr(name) Retrieve the value of the given attribute in name on the first matched element. If the element does not h
given, undefined is returned.
attr(properties) By passing an object literal, you can set many attribute values in one swoop.
attr(key,value) Using this approach will set the attribute and value to all matched elements.
attr(key,fn) This approach uses a function to compute a value, then assigns it to the given attribute.
removeAttr(name) You can also remove the given attribute from all matched elements using this method.
Here, we’ll try out a couple of the different methods for using the .attr() method. First we’ll
use the approach of passing in an object literal, and then we’ll use the method of simply
passing in a key, value pair. These are probably the more common use cases of this
method. The code looks like so:
var li = $('<li><a id="goog" href="" target="">VegiBit</a></li>');
$('li.framework').append(li);
$('#goog').attr({
href: 'http://vegibit.com',
target: '_blank'
});
var i = 0;
var theme = ['alert alert-info',
'alert alert-success',
'alert alert-warning',
'alert alert-info']
$('p').each(function () {
$(this).attr('class', theme[i]);
i++;
});
First, we create a new li element which has an anchor tag in it, but it has
This is pretty cool.
no attributes set. Then we append that li into the DOM after the li which has the class
of framework. Now that it is in the document, we then fetch the anchor tag by it’s id
of #goog. At this point we can use the .attr()method and pass in an object literal which
has both an href property and a target property. This completes our anchor tag, and it is
now a live link that goes to a webpage in a new browser window based on the attributes
we set on it!
The second portion of this example is pretty easy. It’s simply a variation of one of the
examples already covered earlier, but instead of using the .addClass() method, we use
the .attr() method and pass in a key, value pair. What this does is assign the property
with the given value to all matched elements.
Inserting Content With jQuery
jQuery provides many ways to insert new content into the document. Maybe you have
created some new HTML on the fly, grabbed some elements with a selector, or have new
content to insert as a result of a successful AJAX request, in all of these cases you’ll need
some way to actually place this content into the page. You’re most likely familiar with the
append method in jQuery, but there are several more ways to insert content as well. Here
is a table of the most common methods to use for this process.
append(content) Appends the provided content to the inside of all matched elements.
appendTo(selector) Appends the matched elements to a different set of matched elements based on the selector p
elements
prepend(content) Prepends the content given to the inside of all matched elements
prependTo(selector) Prepends the matched elements to a different set of matched elements based on the selector p
elements
after(content) Inserts content after, and outside of all the matched elements
before(content) Inserts content before and outside of all the matched elements
insertAfter(selector) Inserts all of the matched elements after a different set of elements based on the selector give
insertBefore(selector) Inserts all the matched elements before a different set of elements based on the selector passe
We can take a bunch of these methods and apply them to a document to see how they
work. Let’s check out the result!
$('li.markup').append(' <b>is fresh and clean</b> <code>append()</code>');
$('li.presentation').prepend('<code>prepend()</code> <b>Would you like to learn</b> ');
$('li.markup').appendTo('p.markup'); // moves elements
$('li.behavior').prependTo('p.framework'); // moves elements
$('li.presentation').after('<b>This text is inserted <em>after</em> and <em>outside</em></b>
<code>after()</code>');
$('li.presentation').before('<b>This text is inserted <em>before</em> and <em>outside</em></b>
<code>before()</code>');
Note:Click ‘Run It’ below to watch this in action. If you want to try it multiple times, just
refresh this web page after it runs to reset the application and then run again.
As you can see, you can combine all of these different methods to manipulate the page in
any way you like. Just use your imagination and try all kinds of combinations to see what
kinds of effects you come up with.
wrap(html) Wraps each matched element with the specified HTML content
wrapAll(html) Wraps all the elements in the matched set with the specified HTML content
wrapAll(element) Wraps all the elements in the matched set into a single wrapper element
wrapInner(element) Wraps the inner child contents of each matched element with a DOM structure
replaceWith(content) Replaces all matched elements with the specified HTML or DOM elements
replaceAll(selector) Replaces the elements matched by the specified selector with the matched elements
empty() Removes all child nodes from the set of matched elements
clone(bool) Clone matched Dom elements, and all their event handlers, and select the clones
You’ll notice there are two way to implement the .clone() method. This is because by
default when you use this method, it copies the elements, but not any events that may be
bound to those elements. There may be instances when you do want to include those
bindings, since why would you want to go and recreate those bindings if you don’t need
to? In this case, simply pass the true value as the second argument and you’ll have a
copy of the element and any bindings already associated to it.
Like the other groups of methods, we can string a few of these together and create a little
example that shows them in action. If you have your own sandbox development
environment setup, go ahead and test these out as well. Again, repetition and practice will
drive the concepts home! Here is the snippet of jQuery we’ll run in firebug on our example
HTML.
$('p.behavior').wrap('<span class="btn btn-info">');
$('li').wrapAll('<div style="border: 2px solid green">');
$('li.behavior').remove();
$('li.framework').replaceWith('<h3>I was replaced by jQuery</h3>')
$('ul').clone().appendTo('p.framework');
$('ul:last').fadeOut(2500);
Working With CSS Using jQuery
You will often see developers use jQuery to retrieve and update CSS styles on the fly.
There are just a handful of ways to use the .css() method and it is pretty straightforward.
Here they are.
css(name) Returns the value for the named CSS property for the first matched element
css(properties) This option is really convenient. Pass an object literal to the method and set multiple CSS values at on
css(property, Sets a single style property to a value on all matched elements. If a number is given, it will be auto co
value) value, except for z:index, font-weight, opacity, zoom, and line-height.
In addition to directly manipulating the CSS itself, you can do things like simply add a
predefined class. You can also remove and toggle a class with jQuery methods. This
approach is a little easier in my opinion, and it is the approach we have been using so far
to show the effect of jQuery methods on our documents. We happened to take a different
approach for these example. In many tutorials, developers will wrap an element with a
border using the .css() method. In these examples we have been using
the .addClass() and .removeClass() methods to add and remove various predefined
classes from the Twitter Bootstrap framework. It’s pretty cool!
Here are some of those additional CSS methods.
addClass(class) Adds the provided class or classes to each of the matched elements
hasClass(class) Returns true if the given class is present on at least one of the set of matched elem
removeClass(class) Removes all of the given classes from the set of matched elements
toggleClass(class, switch) Adds the class if the switch is true and removes the class if the switch is false
Now that we have covered a lot of the basics with selectors and filters in
jQuery, we’re ready to jump into something that’s a bit more interactive and fun.
What would this be? Well it would be jQuery Event Handling of course! When
using jQuery, the thing that you will do first, and most often, is selecting and
filtering elements. A very close second will be working with JavaScript Event
Handlers by way of jQuery. It is through event handling that we can begin to
add true interactivity and dynamic behavior to our web pages.
• Gives web developers a way to work with events that is much more simplified than
working directly on the DOM.
• Makes different browser implementations of events a non issue via Abstraction.
• Provides web developers a nice time saving technique of binding and unbinding
event handlers to one or many elements by using selectors and filters all at once.
});
You can also use the short-hand version, but I advise against it. Why? The first version,
while slightly more verbose, gives you the exact indication of what it is providing when it is
written. Why complicate your code any more than it needs to be? If you like, use the
following snippet, but we’ll keep on using the first option here
$(function() {
// jQuery here
});
Adding and removing event handlers to elements on the page is as easy as calling either
the .on() or .off() methods in your code. There are a few ways to implement these so
we’ll just whip up some code to examine how they work. Let’s look at a few different
scenarios here:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>jQuery Event Handling</title>
<link rel="stylesheet" href="bootstrap/css/bootstrap.css">
</head>
<body class="container">
<ul id="funlist">
<li class="event1 alert alert-danger">jQuery Event Handling is a simplified Event Handling
Model</li>
<li class="event2 alert alert-info">Reduce Cross Browser Pain</li>
<li class="event3 alert alert-success">Bind and Unbind Events Quickly</li>
<li class="event4 alert alert-warning">All Popular Events Supported</li>
</ul>
</html>
$(document).ready(function () {
$('#theclicker').on('click', clickster);
$('#off').on('click', itsoff);
$('#thefuture').click(function () {
var btn = '<li class="btn btn-default btn-lg btn-block">I am from the Future</li>';
$('#backtothefuture').append(btn);
});
function clickster(evt) {
$('li.event4').toggle();
}
function mickeymouse(evt) {
$('p.markup').toggleClass('bg-info');
}
function itsoff(evt) {
$('#mouseable').off('mouseover mouseleave', mickeymouse);
$('#off').text('The light blue button no longer works!');
}
Oh yeah! This is pretty awesome. We have a few different applications of the .on() method,
we’ll step through them one at a time.
First up we have the line of code which grabs the element with the id of #theclicker and
uses .on() to attach a click event, then run the event handling function named clickster.
In this style, we we pass in a named function as the event handler. We could have also
just passed in an anonymous function, but sometimes the named approach is a little easier
to read in the code. This way we can read it quite easily and know what action is taking
place when the event is triggered. $('#theclicker').on('click', clickster); reads,
“Grab #theclicker element, and when it gets clicked, run the clickster function”. We put
the named functions outside of the $(document).ready(); for easier code reading.
Next up we attach the mouseover and mouseleave events to the element #mouseable.
This shows an example of being able to pass in multiple events as the first argument to
the .on() method. So what this second instance shows us is that any time the user
mouses over, or mouses out of the element which has the id of #mouseable, they are going
to trigger the mickeymouse function. All that function does is simply add a nice blue
background color to one of the paragraph elements in the page. And come on, who
doesn’t love Mickey Mouse?!
The third instance of this example uses the .on() method to actually bind a function which
removes the event handler from the element which has the #mouseable id. If we look at the
code $('#off').on('click', itsoff); it reads as follows. “Select the element with the id
of #off, and when the user clicks it, run the itsoff function.” Lets examine the event
handling function:
function itsoff(evt) {
$('#mouseable').off('mouseover mouseleave', mickeymouse);
$('#off').text('The light blue button no longer works!');
}
So when the itsoff function runs, it grabs the element with the id of #mouseable and uses
the .off()method to remove both the mouseover and mouseleave events from triggering
the mickeymousefunction. Awesome, Donald Duck would be proud.
The last piece of this example is really interesting, and important to understand. We can
use the .on()method as a way to peer into the future of our web page. There will often be
cases where the document gets modified and elements get added dynamically after the
page has loaded. So how can we deal with these newly created elements? How can we
select them, or add event handlers to them? We can do this by taking advantage of the
fact that events bubble in the DOM. What this means is that, when an event happens, if
there is no handler for it, it will bubble up to the parent elements to see if there is a handler
there. In our case, we are adding li elements dynamically as children to a ulelement with
the id of #backtothefuture.
Now, what if we want to take an action, or handle an event for those individual li elements
that have been added to our web page after the fact? We can do this by using
the .on() method on the parent element, and specifying what element(s) we want to take
action on as the second parameter to the .on() method. This is how we do it:
$('#backtothefuture').on('mouseleave', 'li', function () {
$(this).fadeOut().fadeIn();
});
This line of code gives a cool fade in and out effect as the user moves the mouse across
any future lielements that were added. The parent element with the id
of #backtothefuture acts as a container of sorts for all of the li elements that get
dynamically added to the page. We use .on() method and specify 3 parameters. You likely
recognize that parameter 1 is the event we want to bind and parameter 3 is the event
handling function. So what then is parameter 2? Parameter 2 is a selector we specify to
filter the descendants of the original selected item to determine which will trigger the event.
So in this case, it says, any li elements that are descendants of #backtothefuture will
trigger the anonymous function which contains the line of
code $(this).fadeOut().fadeIn(); when the user mouseleaves the element. It is worth
noting, that we can have multiple descendant elements, and they will all work in the same
way. Go ahead and test it out! Click the ‘Click to See The Future’ button multiple times to
insert multiple li elements. Then move your mouse across the collection of li elements
and watch the effect it creates. Pretty cool!
pageX, pageY Document relative coordinates of the mouse when the event triggered
preventDefault() Prevents the Web Browser from executing the default action
Having access to this information is helpful for making different applications and logic in
your jQuery code. Let’s put together some code to show how we can access some of this
information from the jQuery Event Object.
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>jQuery Event Handling</title>
<link rel="stylesheet" href="bootstrap/css/bootstrap.css">
</head>
<body class="container">
<h3>Click the Different Elements, Watch the Event Output Below!</h3>
<div id="one" class="jumbotron alert-success">
<h2>This is div one.</h2>
<a class="btn btn-info" href="#">This is an anchor tag</a> </div>
<div id="two" class="jumbotron alert-info">
<h2>This is div two.</h2>
<span class="btn btn-success" href="#">This is a span tag</span> </div>
<div id="three" class="jumbotron alert-danger">
<h2>This is div three.</h2>
<ul>
<li class="alert alert-warning">list element</li>
<li class="alert alert-success">list element</li>
</ul>
</div>
<div id="output" class="jumbotron alert-warning">
<h2>Your Event Object Data Will Appear Here!</h2>
</div>
});
Let’s understand what is happening in this code. For our markup, we just add some
various HTML elements to the page and add some basic styling to them so that we have
something colorful to look at. We could just as easily have done this example with just
black and white text and no styling, but what fun would that be?! With our HTML in place,
we can set up our jQuery code within the ready handler of our script file. The main idea
here is that when an event handling function runs in jQuery, we can pass in the event to
the function and then access its properties inside of that function. Many times you’ll see
jQuery written with an evt, or event, or just plain e passed into the event handling function.
In our example here, we are using evt, but you can use whatever name you like to
reference the jQuery Event Object so long as the name you pass in, is the one you
reference inside of the event handling function. When we pass in evt, we will then access
the properties of that object inside the function using things
like evt.pageX, evt.pageY, evt.type, evt.target, evt.timeStamp, and so on.
One of the great things about the modern web of today is that there are a lot of
fantastic animations and effects on web pages and User Interfaces. Boring
static text and lame images are gone, slick and engaging experiences are in.
Having these effects can greatly add to the overall navigation, and often gives
the user slick visual cues as to what is the next call to action and so on. It is
important to use these animations and effects as a topping to the cake so to
speak, we don’t want to overdo effects and confuse the user. I’m sure you have
seen some websites that take the visual candy to an extreme, and often times,
this adds no benefit and in fact may detract from the overall experience.
With jQuery, we can create really cool animations and effects, sometimes with
only a quick snippet of code. This is why you neeed to keep an eye on how
much UI sugar you add, because jQuery makes it so easy to do! Once you
have a few tricks up your sleeve, you may be tempted to apply an effect to
every element you ever come across! Use Restraint Young Grapsshopper! If
you use animations and effects correctly, they are going to be a truly awesome
addition to your web page. So with that, let’s jump right into using jQuery to
power our web pages with some awesome animation and effects!
jQuery Animation and Effects
jQuery provides some basic and very useful animation and effects to perform common
actions right out of the box. Creating the effects that these methods provide in native
JavaScript would be a time consuming and probably not all that fun exercise. These
methods in jQuery however allow for things like showing and hiding elements, fading
elements in and out, moving elements around on the screen, and more in a very
straightforward way. It is also possible to create your own custom animations by using
the .animate() method. Using the .animate() method is a bit more advanced though so
instead let’s begin with some of the basic methods to get our feet wet.
show() Shows any elements in the wrapped set, if they are currently hidden
show(speed, callback) By passing in the speed you can control the animation, and also trigger a callback function w
hide() Hides any elements in the wrapped set, if they are currently being shown
hide(speed, callback) You can also pass in a speed and callback to the hide method
toggle(switch) Passing in true shows all elements while passing in false hides all elements
toggle(speed, callback) Pass in a speed to control the animation and trigger a callback function when complete
Now that we have seen what some of these methods are in the table above, let’s put a few
to use in some code to see how they actually work. Here is the raw HTML and jQuery that
make the effect happen. We also have a working example so you can try out the effects for
yourself.
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>jQuery Event Handling</title>
<link rel="stylesheet" href="bootstrap/css/bootstrap.css">
</head>
<body class="container">
<p></p>
<div class="btn btn-lg btn-info" id="show">Show</div>
<div class="btn btn-lg btn-success" id="hide">Hide</div>
<div class="btn btn-lg btn-warning" id="toggle">Toggle</div>
<p></p>
<div id="watch" class="jumbotron alert-info">
<h2>Click The Buttons Above and Watch Me!</h2>
</div>
$(document).ready(function () {
$('#show').click(function () {
$('#watch').show('slow');
});
$('#hide').click(function () {
$('#watch').hide('normal');
});
$('#toggle').click(function () {
$('#watch').toggle('fast');
});
});
.show() In the example above the .show() method is the first that we use. The way it
works is to simply look at the state of the element, and if it is hidden, go ahead and show it.
We also pass in a speed option, in this case slow. Running the .show() method on an
element that is already being shown has no effect.
.hide() The second line of jQuery makes use of the .hide() method and works just
like .show() except it is the opposite in effect. If the element is shown, then go ahead and
hide it. In this case we pass in a speed of normal. Running the .hide() method on an
element that is already hidden also has no effect, just like in the case of .show().
.toggle() This method is quite useful and intelligent in that it can automatically determine if
the matched element(s) are being shown or not. When .toggle() runs, it simply looks at
the current state, and then swaps it with the other. We also have the option to pass in the
speed with this method as well. In this example we pass in the fast option, and as you can
see by clicking above to run the toggle, it looks pretty slick!
Also worth noting is that we are using version three of the Twitter Bootstrap Framework.
This way we can just add classes to our elements as we like, and no need to take the time
to write our own CSS. I’m lazy, oh well.
fadeIn(speed, Fades in all matched elements by changing the opacity assigned to them and triggers an option
callback) function upon completion
fadeOut(speed, Fades out all matched elements by setting opacity to 0 and changing display to none. Triggers
callback) callback on completion
fadeTo(speed, Fades the opacity of all matched elements to a value provided and triggers an optional callbac
callback) complete
With these additional jQuery methods now part of the toolkit, let’s go ahead and check out
some awesome examples.
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>jQuery Event Handling</title>
<link rel="stylesheet" href="bootstrap/css/bootstrap.css">
</head>
<body class="container">
<p></p>
<div class="btn btn-lg btn-info" id="fadein">Fade In</div>
<div class="btn btn-lg btn-success" id="fadeout">Fade Out</div>
<div class="btn btn-lg btn-warning" id="fadeto4">Fade to .4</div>
<div class="btn btn-lg btn-danger" id="fadeup">Fade to 1</div>
<p></p>
<div id="watch" class="jumbotron alert-success">
<h2>Click The Buttons For Cool Fades!</h2>
</div>
$(document).ready(function () {
$('#fadein').click(function () {
$('#watch').fadeIn('slow');
});
$('#fadeout').click(function () {
$('#watch').fadeOut('normal');
});
$('#fadeto4').click(function () {
$('#watch').fadeTo('fast', 0.4);
});
$('#fadeup').click(function () {
$('#watch').fadeTo('slow', 1.0);
});
});
<body class="container">
<p></p>
<div class="btn btn-lg btn-info" id="fadein">Fade In</div>
<div class="btn btn-lg btn-success" id="fadeout">Fade Out</div>
<div class="btn btn-lg btn-warning" id="fadeto4">Fade to .4</div>
<div class="btn btn-lg btn-danger" id="fadeup">Fade to 1</div>
<p></p>
<div id="watch" class="jumbotron alert-success">
<h2>Click The Fade Out</h2>
</div>
$(document).ready(function () {
$('#fadein').click(function () {
$('#watch').fadeIn('slow');
});
$('#fadeout').click(function () {
$('#watch').fadeOut('normal', function () {
setTimeout(function () {
$('#watch').removeClass('jumbotron alert-success').html('<h1>Boo Yeah! Callback
Triggered!</h1>')
.addClass('jumbotron alert-info').fadeIn(10)
}, 1500);
});
});
$('#fadeto4').click(function () {
$('#watch').fadeTo('fast', 0.4);
});
$('#fadeup').click(function () {
$('#watch').fadeTo('slow', 1.0);
});
});
Boo Yeah! I see what you did there. This time around we added a callback to the Fade Out
option. In addition, we used the native JavaScript setTimeout() function to wait an
additional 1.5 seconds before triggering that callback function. This way you get that “Wait
for it….” effect. For more information on how to use setTimeout(), check our the article
that covers Awesome JavaScript Events. Understanding all of the JavaScript events
mentioned there also helps with getting up to speed in handling events in jQuery as well.
Sliding Page Elements with jQuery
Cha Cha this time, left foot this time, slide to the left, slide to the right, everybody clap your
hands! … Oh wait, sorry, too much Nintendo Just Dance happening here. Sliding in jQuery
is not for dancing and moving elements around on the screen, it’s actually another way of
hiding and showing elements, but with a slide effect. You can easily slide elements up or
down in the page, or simply toggle the slide effect as well. Here’s a summary of those slide
methods that are available and how they operate in a nice table format.
slideDown(speed, Displays all matched elements by changing their height, giving a slide effect. You can also
callback) once complete
slideUp(speed, callback) Hides all matched elements by changing their height, giving a slide effect. You can also tr
once complete
slideToggle(speed, Toggles all matched elements by changing their height, giving a slide in and out effect. Yo
callback) a callback once complete
Just like the other methods that we’ve been looking at so far, let’s bust out some code to
see how these effects actually work in real time on a live web page.
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>jQuery Event Handling</title>
<link rel="stylesheet" href="bootstrap/css/bootstrap.css">
</head>
<body class="container">
<p></p>
<div class="btn btn-lg btn-info" id="slideup">Left Foot This Time</div>
<div class="btn btn-lg btn-success" id="slidedown">Right Foot This Time</div>
<div class="btn btn-lg btn-warning" id="toggle">Everybody Clap Your Hands</div>
<p></p>
<div id="watch" class="jumbotron alert-info">
<h2>Cha Cha Real Slow</h2>
</div>
$('#slideup').click(function () {
$('#watch').slideUp('slow');
});
$('#slidedown').click(function () {
$('#watch').slideDown('normal');
});
$('#toggle').click(function () {
$('#watch').slideToggle('fast');
});
});
<body class="container">
<p></p>
<div class="btn btn-lg btn-info" id="top">Left Foot This Time</div>
<div class="btn btn-lg btn-success" id="middle">Right Foot This Time</div>
<div class="btn btn-lg btn-warning" id="bottom">Everybody Clap Your Hands</div>
<p></p>
<div id="watch1" class="jumbotron alert-info">
<h2>Cha Cha Real Slow</h2>
</div>
<div class="jumbotron alert-success">
<h2 id="watch2" >Just Bust a Move</h2>
</div>
<div id="watch3" class="jumbotron alert-warning">
<h2>If you want it, you got it</h2>
</div>
$("#top").click(function () {
$("#watch1").animate({
borderRadius: 100,
paddingBottom: 24,
paddingTop: 24
}, 1000);
});
$("#middle").click(function () {
$("#watch2").animate({
fontSize: 75
}, 2000);
});
$("#bottom").click(function () {
$("#watch3").animate({
paddingLeft: 300
}, 1000, "swing");
});
});
So what do we notice about this code here? That’s right friends, we are directly
manipulating CSS values, and they can only be values of a numeric type! What is
interesting about this particular example is that we are using the Twitter Bootstrap
Framework to decorate our HTML as a starting point. Normally, you would have a
stylesheet that assigns various CSS properties to certain values and those are applied to
the elements on the page via id’s or classes. It works if you are using a framework as well.
The key to remember is that, any property that you are trying to animate must already be
applied to the HTML element to begin with. For example, if you want to animate a border-
radius to 100px on a particular element, that element must first at least have that property
set to some other value. In this case, the original border-radius value was 6px. If the
particular element had no border-radius property to begin with, well then, your animation is
not going to work so well is it?!
Enough talk, show me the effects!
The benefit with using the custom animation option is again, you get very
Fun Stuff Indeed!
granular control over the exact values of the CSS styles assigned to your various elements
on the page. Some of the animations out there on the web today are really incredible. I’m
sure you have seem some that have really made you wonder how the effect was
accomplished as well. If you have enough patience, creativity, and imagination, you will
also be creating custom animations that will knock peoples socks off!
AJAX is in use all over the internet today. By using AJAX, your website can get
data from remote services and communicate with your web server without a full
page refresh. In recent times, AJAX has really become one of the major
components of building modern web applications. It can be a little tricky to
implement in native JavaScript, but by using jQuery, it does become a whole lot
easier. Let’s examine how working with AJAX in jQuery can benefit you and
your webpages!
The AJAX function in jQuery
The first way you can work with AJAX in jQuery is to use the actual .ajax() method in the
library. The .ajax() method is more of a low level interface rather than the more simplified
AJAX helper methods that we will discuss shortly. For now, let’s just whip up some code
and examine how it works.
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>jQuery Event Handling</title>
<link rel="stylesheet" href="bootstrap/css/bootstrap.css">
</head>
<body class="container">
<p></p>
<div id="content" class="jumbotron">
<span id="click" class="btn btn-primary">Run AJAX!</span>
</div>
<div class="alert">
</div>
<script src="jquery-1.11.1.js"></script>
<!-- Include all compiled plugins (below), or include individual files as needed -->
<script src="bootstrap/js/bootstrap.js"></script>
<!-- custom written js -->
<script src="tut.js"></script>
</body>
</html>
$(document).ready(function () {
function getText() {
$.ajax({
// the URL for the request
url: 'sometext.txt',
function successFunction(result) {
$('#content').append(result);
}
$('#click').click(function () {
getText();
});
});
With this code in place we can test out the AJAX that gets triggered when we click the
button. First we’ll just click the button to run the code and see what happens.
This looks perfect. The function is run when we click, that data is loaded into the page, the
status is displayed, and the button becomes disabled to prevent multiple clicks causing the
same data to load into the page over and over again. Ok, now let’s rename the text file on
the sever to something else and try again. We can see the result here.
Oh No! This time the AJAX request has failed because the file it is looking for is not there. In
this case, error information is displayed to the screen based on the JavaScript we had
written for a failure scenario. Note that in both instances, we leave the firebug console
open and we can see the request being made of the server from the browser. You have
the ability to inspect the Headers, Response, HTML, and Cookies associated with the
AJAX request being made and this comes in really handy during debugging of your
application.
It all works quite easily, but there is a fair amount happening in the JavaScript demo here.
It pays to review how this all works. First, let’s begin with analyzing the information that we
are passing to the .ajax() method. In this example, we pass 6 properties via an object to
the .ajax() method. Note that items in an object appear in between { curly braces } and
are separated by a comma.
• url The url property is where we are directing this request to. This must be an url on
the same domain as the current web page.
• type In this property we can specify whether this will be a POST or
a GET request. GET is used for simple data retrieval while POST would be used in form
submission, database updates, or some other process that modifies data.
• dataType The dataType property declares the type of information we are hoping to
get back from our request.
• success The success property holds a function which gets triggered upon a
successful AJAX request.
• error The error property holds a function that gets triggered if there is an error
during the AJAX request.
• complete The complete property holds holds a function which gets triggered
regardless of success or failure. This function will run no matter what.
Having these properties memorized will make it easy for you to do basic ajax requests in
your web application. Do note that there are tons more properties and methods to deal
with when using the low level interface for AJAX requests in jQuery. If you want to just get
up and running quickly however, this example here gives you a fantastic blueprint to do so.
function getText() {
$.get('sometext.txt', successFunction);
$('#click').addClass('disabled');
}
function successFunction(result) {
$('#content').append(result);
}
$('#click').click(function () {
getText();
});
$.ajaxSetup({
// Disable caching of AJAX responses
cache: false
});
});
With this updated code, we can run the function by clicking our button and observe the
result.
Awesome! As you can see when this code ran, it was successful. That brings up a good point
to note with the $.get() method! There is no way to set an error handler when using this
shorthand method, you would need to use the $.ajax() method we discussed first! So you
see, we do get the benefit of a more terse syntax, however if you need that granular
control, it is better to use the low level function to get it done. Another point to note here is
that we did make use of the $.ajaxSetup() method to turn off caching. This was so that we
could change the text in our test file, and jQuery would return the new data rather than the
cached version in the browser. Had we not taken this step, the text displayed on the
screen would still be from the prior example and we certainly don’t want that! We can also
set all of the options available in the standard $.ajax() method, so if you really want to use
these shorthand methods and still have fine tuned control, you can use $.ajaxSetup() to
do so.
Using the jQuery .load() Method
The action of using the $.get() method along with a user defined success function to load
the response into the existing web page is very common. It is so common in fact, that
jQuery provides a shorthand way to accomplish this in one step. We can rewrite our AJAX
request again using this approach.
$(document).ready(function () {
function getText() {
$('#content').load('sometext.txt');
}
$('#click').click(function () {
getText();
});
$.ajaxSetup({
// Disable caching of AJAX responses
cache: false
});
});
Awesome! It does work, but do you notice anything different? Yes that’s right, the button that
we have been attaching a click event to is missing after we run the code. This is because,
with the .load()method, any HTML or text within the specified selector will be replaced
with the returned data from the AJAX call. In the other examples, the button remained
because in our success function we were appending to the content, but again,
with .load() content is replaced. Get It? Got It. Good!
<head>
<meta charset="utf-8">
<title>jQuery Event Handling</title>
<link rel="stylesheet" href="bootstrap/css/bootstrap.css">
</head>
<body class="container">
<p></p>
<span id="click" class="btn btn-primary">Fetch Data From Flickr!</span>
<p></p>
<div id="content" class="jumbotron">
</div>
<div class="alert">
</div>
<script src="jquery-1.11.1.js"></script>
<!-- Include all compiled plugins (below), or include individual files as needed -->
<script src="bootstrap/js/bootstrap.js"></script>
<!-- custom written js -->
<script src="tut.js"></script>
</body>
</html>
$(document).ready(function () {
function fetchFlickrJSONData() {
var flickrAPI = 'http://api.flickr.com/services/feeds/photos_public.gne?jsoncallback=?';
$.getJSON(flickrAPI, {
tags: 'Ocean',
tagmode: 'any',
format: 'json'
},
successFunction);
}
function successFunction(result) {
$.each(result.items, function (i, item) {
$('<img>').attr('src', item.media.m).appendTo('#content');
});
}
$.ajaxSetup({
// Disable caching of AJAX responses
cache: false
});
});
Cool!As you can see, upon clicking the button, our little web app goes out to the Flickr API
and fetches a bunch of images. Those images are actually just a collection of data given to
us from the Flickr API. We would need to take a look at the return result to understand how
to use that information in our page.
This is the raw JSON data that the Flickr API sends to us when we click the button to fetch
images.
jQuery111104020101139715232_1401317867081({
"title":"Recent Uploads tagged ocean",
"link":"http://www.flickr.com/photos/tags/ocean/",
"description":"",
"modified":"2014-05-28T22:53:31Z",
"generator":"http://www.flickr.com/",
"items":[
{
"title":"lost in the city of angels",
"link":"http://www.flickr.com/photos/deguet/14293974855/",
"media":{
"m":"http://farm3.staticflickr.com/2909/14293974855_6d15767781_m.jpg"
},
"date_taken":"2009-05-26T23:45:39-08:00",
"description":" <p><a href="http://www.flickr.com/people/deguet/">coralynes</a> posted a
photo:</p> <p><a href="http://www.flickr.com/photos/deguet/14293974855/" title="lost in the city of
angels"><img src="http://farm3.staticflickr.com/2909/14293974855_6d15767781_m.jpg" width="240"
height="160" alt="lost in the city of angels" /></a></p> <p></p>",
"published":"2014-05-28T22:53:31Z",
"author":"nobody@flickr.com (coralynes)",
"author_id":"54978430@N07",
"tags":"ocean city sky aracaju sergipe"
},
{
"title":"",
"link":"http://www.flickr.com/photos/nilspix/14292026192/",
"media":{
"m":"http://farm4.staticflickr.com/3825/14292026192_b4edab6898_m.jpg"
},
"date_taken":"2014-05-26T07:50:28-08:00",
"description":" <p><a href="http://www.flickr.com/people/nilspix/">NilsPix</a> posted a
photo:</p> <p><a href="http://www.flickr.com/photos/nilspix/14292026192/" title=""><img
src="http://farm4.staticflickr.com/3825/14292026192_b4edab6898_m.jpg" width="240" height="161" alt=""
/></a></p> ",
"published":"2014-05-28T22:50:26Z",
"author":"nobody@flickr.com (NilsPix)",
"author_id":"74997357@N03",
"tags":"ocean sea beach clouds sand surf longisland shore jonesbeach"
},
{
"title":"Ucluelet, BC - View from the Black Rock Resort",
"link":"http://www.flickr.com/photos/freshairphotography/14290639751/",
"media":{
"m":"http://farm4.staticflickr.com/3779/14290639751_4a75069b14_m.jpg"
},
"date_taken":"2014-05-26T17:34:36-08:00",
"description":" <p><a
href="http://www.flickr.com/people/freshairphotography/">Freshairphotography</a> posted a photo:</p>
<p><a href="http://www.flickr.com/photos/freshairphotography/14290639751/" title="Ucluelet, BC - View
from the Black Rock Resort"><img
src="http://farm4.staticflickr.com/3779/14290639751_4a75069b14_m.jpg" width="160" height="240"
alt="Ucluelet, BC - View from the Black Rock Resort" /></a></p> <p>Looking directly out to the
Pacific from our room at the Black Rock Resort was such a feast for the eyes. Listening to the waves
crashing along the shoreline rocks/bluffs - the sea birds singing and calling out to each other -
pure bliss for 2 days!</p>",
"published":"2014-05-28T22:56:11Z",
"author":"nobody@flickr.com (Freshairphotography)",
"author_id":"93408882@N03",
"tags":"ocean blue trees light sunlight canada tree tourism beach nature colors beautiful
beauty clouds forest canon island evening coast amazing interesting rainforest rocks bc view natural
pacific hiking path relaxing trails peaceful sealife tourist hike vancouverisland trail pacificocean
views windswept greens tofino serene westcoast tidal ucluelet nationalgeographic crashingwaves
rockformation oceanspray oldgrowthforest beautifulbc blackrockresort explorebc canon7d explorecanada
ilovebc explorevancouverisland"
},
{
"title":"Might as well",
"link":"http://www.flickr.com/photos/fortheride/14314138973/",
"media":{
"m":"http://farm3.staticflickr.com/2907/14314138973_9f32e94784_m.jpg"
},
"date_taken":"2014-05-18T13:37:17-08:00",
"description":" <p><a href="http://www.flickr.com/people/fortheride/">Kraften</a> posted a
photo:</p> <p><a href="http://www.flickr.com/photos/fortheride/14314138973/" title="Might as
well"><img src="http://farm3.staticflickr.com/2907/14314138973_9f32e94784_m.jpg" width="240"
height="135" alt="Might as well" /></a></p> <p>Dolphins jumping off the coast via 500px <a
href="http://ift.tt/1itp09r" rel="nofollow">ift.tt/1itp09r</a></p>",
"published":"2014-05-28T22:42:23Z",
"author":"nobody@flickr.com (Kraften)",
"author_id":"94135442@N00",
"tags":"ocean california sea water animals swim pacific dolphins 500px ifttt"
},
{
"title":"Placid Pacific",
"link":"http://www.flickr.com/photos/darrenbarnes/14107447127/",
"media":{
"m":"http://farm6.staticflickr.com/5474/14107447127_63625f9399_m.jpg"
},
"date_taken":"2014-04-28T18:50:20-08:00",
"description":" <p><a href="http://www.flickr.com/people/darrenbarnes/">Dwood
Photography</a> posted a photo:</p> <p><a
href="http://www.flickr.com/photos/darrenbarnes/14107447127/" title="Placid Pacific"><img
src="http://farm6.staticflickr.com/5474/14107447127_63625f9399_m.jpg" width="240" height="152"
alt="Placid Pacific" /></a></p> <p>Looking out onto the <a
href="http://en.wikipedia.org/wiki/Pacific_Ocean" rel="nofollow">mighty Pacific Ocean</a>. On this
evening it had a placid feel about it.<br /> <br /> This shot was taken 12 mins prior to this <a
href="https://www.flickr.com/photos/darrenbarnes/14208163233/in/photostream/">previous post</a>. I
usually prefer a stronger foreground element in my beach scenes, but sometimes you just have to work
with what you have, and in this case I thought the sun glow on the sand served as a nice focal
point.<br /> <br /> Thanks for looking.<br />
_________________________________________________________________<br /> Comments and constructive
criticism always appreciated.<br /> <a href="http://en.flickeflu.com/photos/9828874@N02"
rel="nofollow">Stream on Black</a>....<a href="http://www.facebook.com/DwoodPhotography"
rel="nofollow">Follow on Facebook</a>....<a href="http://www.flickr.com/people/darrenbarnes/">My
Profile (to get to webpage)</a></p>",
"published":"2014-05-28T22:49:10Z",
"author":"nobody@flickr.com (Dwood Photography)",
"author_id":"9828874@N02",
"tags":"ocean california ca pink blue seascape yellow landscape sand pacific pacificocean
placid dwoodphotography dwoodphotographycom placidpacific"
},
{
"title":"Fishing Boat",
"link":"http://www.flickr.com/photos/pavlinajane/14107296278/",
"media":{
"m":"http://farm4.staticflickr.com/3825/14107296278_aac9856567_m.jpg"
},
"date_taken":"2014-05-28T10:40:27-08:00",
"description":" <p><a href="http://www.flickr.com/people/pavlinajane/">pavlinajane</a>
posted a photo:</p> <p><a href="http://www.flickr.com/photos/pavlinajane/14107296278/" title="Fishing
Boat"><img src="http://farm4.staticflickr.com/3825/14107296278_aac9856567_m.jpg" width="240"
height="160" alt="Fishing Boat" /></a></p> ",
"published":"2014-05-28T22:42:27Z",
"author":"nobody@flickr.com (pavlinajane)",
"author_id":"60291025@N05",
"tags":"ocean old travel blue sunset sea summer vacation sky white lake fish male net
industry beach nature water silhouette sport illustration river landscape evening coast harbor boat
fishing fisherman marine ship outdoor seagull horizon transport wave vessel hobby line commercial
shore transportation rod catch leisure recreation hastings nautical activity fishingboat vector
trawler reel"
},
{
"title":"San Francisco Sunrise - HDR",
"link":"http://www.flickr.com/photos/82955120@N05/14270818136/",
"media":{
"m":"http://farm4.staticflickr.com/3807/14270818136_2eb320ae8d_m.jpg"
},
"date_taken":"2013-12-29T07:54:20-08:00",
"description":" <p><a href="http://www.flickr.com/people/82955120@N05/">Free HDR &
Photomanipulations - www.freestock.ca</a> posted a photo:</p> <p><a
href="http://www.flickr.com/photos/82955120@N05/14270818136/" title="San Francisco Sunrise -
HDR"><img src="http://farm4.staticflickr.com/3807/14270818136_2eb320ae8d_m.jpg" width="240"
height="160" alt="San Francisco Sunrise - HDR" /></a></p> <p>Early morning photo of San Francisco,
California (USA), as seen from Twin Peaks. HDR composite from multiple exposures.<br /> <br /> This
photo is released under a standard Creative Commons License - Attribution 3.0 Unported. It gives you
a lot of freedom to use my work commercially as long as you credit and link back to the <b><a
href="http://freestock.ca/americas_g98-san_francisco_sunrise__hdr_p4613.html" target="_blank"
rel="nofollow">same free image</a></b> from my website, <b><a href="http://www.freestock.ca"
target="_blank" rel="nofollow">www.freestock.ca</a></b></p>",
"published":"2014-05-28T22:42:10Z",
"author":"nobody@flickr.com (Free HDR & Photomanipulations - www.freestock.ca)",
"author_id":"82955120@N05",
"tags":"ocean california road street city morning travel bridge trees sea sky urban usa sun
mountain streets building tree tourism water beautiful beauty grass architecture america sunrise
buildings river landscape outside outdoors dawn bay early us construction scenery san francisco glow
cityscape exterior angle pacific image outdoor united stock wide scenic picture landmarks free twin
wideangle landmark scene architectural line hills foliage american nicolas transportation area
glowing raymond states roads peaks rise hdr resource cityline somadjinn"
},
{
"title":"Hastings view",
"link":"http://www.flickr.com/photos/pavlinajane/14293878425/",
"media":{
"m":"http://farm4.staticflickr.com/3795/14293878425_a2f481d29b_m.jpg"
},
"date_taken":"2014-05-28T10:27:42-08:00",
"description":" <p><a href="http://www.flickr.com/people/pavlinajane/">pavlinajane</a>
posted a photo:</p> <p><a href="http://www.flickr.com/photos/pavlinajane/14293878425/"
title="Hastings view"><img src="http://farm4.staticflickr.com/3795/14293878425_a2f481d29b_m.jpg"
width="240" height="160" alt="Hastings view" /></a></p> ",
"published":"2014-05-28T22:31:16Z",
"author":"nobody@flickr.com (pavlinajane)",
"author_id":"60291025@N05",
"tags":"ocean trip travel blue sunset sea summer vacation sky sun holiday fish seascape
tourism beach nature water beautiful architecture port relax landscape outdoors island bay coast
harbor boat town seaside fishing fisherman sand scenery europe paradise mediterranean ship view yacht
outdoor turquoise horizon scenic wave sunny coastal shore coastline recreation hastings idyllic
tranquil hastingscoast hastingsboat finingboat"
},
{
"title":"Coral Grouper at Seaventures rig",
"link":"http://www.flickr.com/photos/whitcomberd/14107266438/",
"media":{
"m":"http://farm4.staticflickr.com/3748/14107266438_828b0892fe_m.jpg"
},
"date_taken":"2014-04-23T13:00:11-08:00",
"description":" <p><a href="http://www.flickr.com/people/whitcomberd/">WhitcombeRD</a>
posted a photo:</p> <p><a href="http://www.flickr.com/photos/whitcomberd/14107266438/" title="Coral
Grouper at Seaventures rig"><img
src="http://farm4.staticflickr.com/3748/14107266438_828b0892fe_m.jpg" width="240" height="190"
alt="Coral Grouper at Seaventures rig" /></a></p> <p>Coral Grouper and glassfish around an underwater
wreck</p>",
"published":"2014-05-28T22:34:40Z",
"author":"nobody@flickr.com (WhitcombeRD)",
"author_id":"8705027@N03",
"tags":"ocean life blue school red sea wild fish seascape color nature water animal coral
metal marine colorful aqua asia soft underwater wildlife debris bottom under pipe egypt conservation
tire scuba diving artificial snorkeling exotic pollution malaysia tropical manmade environment
caribbean aquatic wreck reef wreckage tyres biodiversity grouper shoal encrusted glassfish"
},
{
"title":"Riverbed by John R. Pleak",
"link":"http://www.flickr.com/photos/102476184@N02/14314112073/",
"media":{
"m":"http://farm4.staticflickr.com/3695/14314112073_fcb1f13279_m.jpg"
},
"date_taken":"2014-05-28T15:52:17-08:00",
"description":" <p><a href="http://www.flickr.com/people/102476184@N02/">johnr.pleak</a>
posted a photo:</p> <p><a href="http://www.flickr.com/photos/102476184@N02/14314112073/"
title="Riverbed by John R. Pleak"><img
src="http://farm4.staticflickr.com/3695/14314112073_fcb1f13279_m.jpg" width="179" height="240"
alt="Riverbed by John R. Pleak" /></a></p> <p>Digital photograph of a riverbed by John R. Pleak
2014</p>",
"published":"2014-05-28T22:38:50Z",
"author":"nobody@flickr.com (johnr.pleak)",
"author_id":"102476184@N02",
"tags":"ocean sea art nature water creek river fishing stream artist underwater wildlife
scubadiving nationalgeographic marinelife 2014 scubadiver curent johnrpleak johnpleak"
},
{
"title":"House Rose door",
"link":"http://www.flickr.com/photos/pavlinajane/14314022953/",
"media":{
"m":"http://farm4.staticflickr.com/3730/14314022953_50563b047e_m.jpg"
},
"date_taken":"2014-05-28T10:19:47-08:00",
"description":" <p><a href="http://www.flickr.com/people/pavlinajane/">pavlinajane</a>
posted a photo:</p> <p><a href="http://www.flickr.com/photos/pavlinajane/14314022953/" title="House
Rose door"><img src="http://farm4.staticflickr.com/3730/14314022953_50563b047e_m.jpg" width="160"
height="240" alt="House Rose door" /></a></p> ",
"published":"2014-05-28T22:21:40Z",
"author":"nobody@flickr.com (pavlinajane)",
"author_id":"60291025@N05",
"tags":"ocean sea wild food white fish cooking water animal rose illustration dinner emblem
menu lunch cuisine restaurant lemon healthy fishing marine mediterranean raw dish market eating
background label tag salmon rubber fresh rye stamp gourmet business delicious eat meal seafood catch
diet cooked rosegarden vector culinary isolated preparation freshness saltwater nutrition ingredient
prepared rosehouse rosedoor roseuk ryerosedoor"
},
{
"title":"B&W Clouds",
"link":"http://www.flickr.com/photos/ulfurbjornsson/14290465641/",
"media":{
"m":"http://farm4.staticflickr.com/3669/14290465641_676136c7b1_m.jpg"
},
"date_taken":"2014-05-16T16:35:23-08:00",
"description":" <p><a href="http://www.flickr.com/people/ulfurbjornsson/">Úlfur
Björnsson</a> posted a photo:</p> <p><a
href="http://www.flickr.com/photos/ulfurbjornsson/14290465641/" title="B&W Clouds"><img
src="http://farm4.staticflickr.com/3669/14290465641_676136c7b1_m.jpg" width="240" height="183"
alt="B&W Clouds" /></a></p> <p>Faroe Islands trip, 14th-20th of May.</p>",
"published":"2014-05-28T22:26:44Z",
"author":"nobody@flickr.com (Úlfur Björnsson)",
"author_id":"45906481@N08",
"tags":"ocean trip sea summer vacation bw white black rain clouds canon landscape islands
faroe 6d 70200mm færeyjar úlfur"
},
{
"title":"Seafaring Mallard",
"link":"http://www.flickr.com/photos/109773589@N08/14107071629/",
"media":{
"m":"http://farm3.staticflickr.com/2916/14107071629_d8ab57db01_m.jpg"
},
"date_taken":"2014-05-24T02:27:44-08:00",
"description":" <p><a
href="http://www.flickr.com/people/109773589@N08/">pakhouse@att.net</a> posted a photo:</p> <p><a
href="http://www.flickr.com/photos/109773589@N08/14107071629/" title="Seafaring Mallard"><img
src="http://farm3.staticflickr.com/2916/14107071629_d8ab57db01_m.jpg" width="240" height="184"
alt="Seafaring Mallard" /></a></p> ",
"published":"2014-05-28T22:13:06Z",
"author":"nobody@flickr.com (pakhouse@att.net)",
"author_id":"109773589@N08",
"tags":"ocean duck flight mallard seashore"
},
{
"title":"Pulau Sabang Seascape",
"link":"http://www.flickr.com/photos/curseshadow/14293297064/",
"media":{
"m":"http://farm4.staticflickr.com/3735/14293297064_dd773d34be_m.jpg"
},
"date_taken":"2014-05-14T19:44:08-08:00",
"description":" <p><a href="http://www.flickr.com/people/curseshadow/">Zulhatfi Aziz
Photography</a> posted a photo:</p> <p><a
href="http://www.flickr.com/photos/curseshadow/14293297064/" title="Pulau Sabang Seascape"><img
src="http://farm4.staticflickr.com/3735/14293297064_dd773d34be_m.jpg" width="156" height="240"
alt="Pulau Sabang Seascape" /></a></p> <p>Taken using : Nikon D700 + Nikon 16-35mm f4 + Schneider 10
stops ND filter.<br /> <br /> <br /> Appreciate if you can show your support by clicking the
'Like'<br /> button on my facebook page. <a href="http://www.facebook.com/zulhatfiazizphotography"
rel="nofollow">www.facebook.com/zulhatfiazizphotography</a><br /> <br /> <br /> This is my official
website & twitter<br /> <a href="http://www.curseshadow.com"
rel="nofollow">www.curseshadow.com</a><br /> <a href="http://www.twitter.com/zulhatfiaziz"
rel="nofollow">www.twitter.com/zulhatfiaziz</a><br /> <br /> <br /> I hope you're not using this
image on any websites, blogs or any media<br /> without my permission. © All rights reserved. This
picture is taken in<br /> only single shot. No HDR technique in this image.</p>",
"published":"2014-05-28T22:19:22Z",
"author":"nobody@flickr.com (Zulhatfi Aziz Photography)",
"author_id":"10860615@N04",
"tags":"ocean trip travel light sunset sea summer vacation sky blackandwhite bw white
holiday seascape motion black color beach water rain weather clouds port indonesia lens landscape
island photography dawn evening coast photo sand nikon long exposure waves colours outdoor south hard
scenic dramatic places explore southern tsunami filter malaysia langkawi rise dickson aceh heavy grad
raining pulau aziz ache sabang atjeh singhray d700 zulhatfi zulhatfiaziz"
},
{
"title":"Moments In LOve",
"link":"http://www.flickr.com/photos/88642461@N05/14038591469/",
"media":{
"m":"http://farm6.staticflickr.com/5567/14038591469_ed55e1da46_m.jpg"
},
"date_taken":"2014-05-19T17:35:55-08:00",
"description":" <p><a href="http://www.flickr.com/people/88642461@N05/">darla96</a> posted a
photo:</p> <p><a href="http://www.flickr.com/photos/88642461@N05/14038591469/" title="Moments In
LOve"><img src="http://farm6.staticflickr.com/5567/14038591469_ed55e1da46_m.jpg" width="240"
height="149" alt="Moments In LOve" /></a></p> <p>Moments in love...Quiet Storm Remix here<br /> <a
href="http://www.youtube.com/watch?v=u32NM_2wq34"
rel="nofollow">www.youtube.com/watch?v=u32NM_2wq34</a><br /> <br /> <a
href="http://www.cameralenscompare.com/photoAwardsCounterDetails.aspx?PhotoId=14038591469&user=darla9
6" rel="nofollow">www.cameralenscompare.com/photoAwardsCounterDetails.aspx?...</a></p>",
"published":"2014-05-28T22:07:50Z",
"author":"nobody@flickr.com (darla96)",
"author_id":"88642461@N05",
"tags":"ocean girls art beach water photoshop model waves arty phone florida miami models
creative babe concept bathing mermaid darla tanning sunning celll darla96"
},
{
"title":"Moonlight Mile",
"link":"http://www.flickr.com/photos/88642461@N05/14292096874/",
"media":{
"m":"http://farm6.staticflickr.com/5117/14292096874_4ac89f3715_m.jpg"
},
"date_taken":"2014-05-28T14:24:52-08:00",
"description":" <p><a href="http://www.flickr.com/people/88642461@N05/">darla96</a> posted a
photo:</p> <p><a href="http://www.flickr.com/photos/88642461@N05/14292096874/" title="Moonlight
Mile"><img src="http://farm6.staticflickr.com/5117/14292096874_4ac89f3715_m.jpg" width="240"
height="109" alt="Moonlight Mile" /></a></p> ",
"published":"2014-05-28T22:07:59Z",
"author":"nobody@flickr.com (darla96)",
"author_id":"88642461@N05",
"tags":"ocean sea woman white black sexy art beach water swim photoshop pose model sand
shoot waves arty photoshoot body creative babe moonlight concept darla mile darla96"
},
{
"title":"The Depth of My Soul",
"link":"http://www.flickr.com/photos/88642461@N05/9213109880/",
"media":{
"m":"http://farm6.staticflickr.com/5527/9213109880_4ef542762d_m.jpg"
},
"date_taken":"2013-07-04T20:35:38-08:00",
"description":" <p><a href="http://www.flickr.com/people/88642461@N05/">darla96</a> posted a
photo:</p> <p><a href="http://www.flickr.com/photos/88642461@N05/9213109880/" title="The Depth of My
Soul"><img src="http://farm6.staticflickr.com/5527/9213109880_4ef542762d_m.jpg" width="240"
height="99" alt="The Depth of My Soul" /></a></p> <p><a
href="http://www.cameralenscompare.com/photoAwardsCounterDetails.aspx?PhotoId=9213109880&user=darla96
" rel="nofollow">www.cameralenscompare.com/photoAwardsCounterDetails.aspx?...</a></p>",
"published":"2014-05-28T22:07:53Z",
"author":"nobody@flickr.com (darla96)",
"author_id":"88642461@N05",
"tags":"ocean light sky sun art water clouds photoshop arty legs creative soul a3 concept
darla начинизавиждане blinkagain darla96 infinitexposurel1p1"
},
{
"title":"Are You Game?",
"link":"http://www.flickr.com/photos/88642461@N05/14273445203/",
"media":{
"m":"http://farm3.staticflickr.com/2900/14273445203_afcc9f84da_m.jpg"
},
"date_taken":"2014-05-23T18:40:03-08:00",
"description":" <p><a href="http://www.flickr.com/people/88642461@N05/">darla96</a> posted a
photo:</p> <p><a href="http://www.flickr.com/photos/88642461@N05/14273445203/" title="Are You
Game?"><img src="http://farm3.staticflickr.com/2900/14273445203_afcc9f84da_m.jpg" width="240"
height="116" alt="Are You Game?" /></a></p> <p><a
href="http://www.cameralenscompare.com/photoAwardsCounterDetails.aspx?PhotoId=14273445203&user=darla9
6" rel="nofollow">www.cameralenscompare.com/photoAwardsCounterDetails.aspx?...</a></p>",
"published":"2014-05-28T22:07:54Z",
"author":"nobody@flickr.com (darla96)",
"author_id":"88642461@N05",
"tags":"ocean girls art beach water photoshop model waves arty phone florida miami models
creative babe bikini spitfire concept bathing mermaid darla tanning vollyball sunning celll darla96"
},
{
"title":"Heaven's Hell",
"link":"http://www.flickr.com/photos/88642461@N05/14020491819/",
"media":{
"m":"http://farm6.staticflickr.com/5503/14020491819_f48384a86a_m.jpg"
},
"date_taken":"2014-05-17T15:01:11-08:00",
"description":" <p><a href="http://www.flickr.com/people/88642461@N05/">darla96</a> posted a
photo:</p> <p><a href="http://www.flickr.com/photos/88642461@N05/14020491819/" title="Heaven's
Hell"><img src="http://farm6.staticflickr.com/5503/14020491819_f48384a86a_m.jpg" width="240"
height="104" alt="Heaven's Hell" /></a></p> <p><a
href="http://www.cameralenscompare.com/photoAwardsCounterDetails.aspx?PhotoId=14020491819&user=darla9
6" rel="nofollow">www.cameralenscompare.com/photoAwardsCounterDetails.aspx?...</a></p>",
"published":"2014-05-28T22:07:48Z",
"author":"nobody@flickr.com (darla96)",
"author_id":"88642461@N05",
"tags":"ocean morning sea sky sun seascape color art beach water sunshine clouds photoshop
skulls fire death sand heaven waves arty god hell creative vivid blessing soul concept rise darla
revolt sunscape darla96"
},
{
"title":"vīvere",
"link":"http://www.flickr.com/photos/mohan_berg/14107058739/",
"media":{
"m":"http://farm3.staticflickr.com/2900/14107058739_24427401c4_m.jpg"
},
"date_taken":"2014-05-28T18:01:56-08:00",
"description":" <p><a href="http://www.flickr.com/people/mohan_berg/">discovery720266</a>
posted a photo:</p> <p><a href="http://www.flickr.com/photos/mohan_berg/14107058739/"
title="vīvere"><img src="http://farm3.staticflickr.com/2900/14107058739_24427401c4_m.jpg" width="240"
height="120" alt="vīvere" /></a></p> <p>NOTE: All credit goes to the original photographer at 500px!
" via 500px <a href="http://ift.tt/1kIVsZV"" rel="nofollow">ift.tt/1kIVsZV"</a>;</p>",
"published":"2014-05-28T22:01:56Z",
"author":"nobody@flickr.com (discovery720266)",
"author_id":"96723055@N08",
"tags":"ocean sea woman female clouds hawaii underwater dreamy form 500px ifttt"
}
]
})
Whoa! That’s a lot of information! It does look like a lot of information to navigate through,
but it is fairly straightforward if we follow the conventions of JSON. JSON really just boils
down to name / value pairs. We can see that in the items array of the returned JSON,
there are many properties. It should make sense if you examine the JavaScript code what
it is doing with the returned JSON data. Let’s modify our success function to use more
properties from the items array so we understand exactly how to tap into each value.
function fetchFlickrJSONData() {
var flickrAPI = 'http://api.flickr.com/services/feeds/photos_public.gne?jsoncallback=?';
$.getJSON(flickrAPI, {
tags: 'Ocean',
tagmode: 'any',
format: 'json'
},
successFunction);
}
function successFunction(result) {
$.each(result.items, function (i, item) {
var title = item.title;
var link = item.link;
var imgsrc = item.media.m;
var image = '<a href="' + link + '" title="' + title + '"><img src="' + imgsrc + '" /></a>';
$(image).appendTo('#content');
});
}
This code starts by making a call to the Flickr API with the jQuery $.getJSON() method.
The three parameters we pass to it are the url of the JSON API, an object containing
properties of information we’d like from the API, and lastly a function to run on
success. Perfect.
Inside the successFunction() we access the returned data from the JSON request and
build up an image with the data we’d like, and append that to our #content div in the HTML
page. The function accepts the result as it’s only parameter. The response has
many items in it, so we iterate over all of them using $.each(). Note! This is not the same
as $(selector).each(), which is used to iterate over a jQuery object. This version can iterate
over any collection, whether it is an object or an array. The first parameter to this method is
the collection of items in question, and a function to run on each iteration. The anonymous
function take two parameters, the first being the index of the collection, and the second
being the collection itself. In our example we use i and item to refer to each item in the
collection. We could just as easily passed in tom and jerry, and it would still work so long
as we reference those items using that notation within the function. Inside this function we
then simply declare a few variables and populate them with the data from the returned
JSON. Then we build up an image surrounded by an a tag, and append each one to
the #content div in the page. This is really cool, as now when we load the data, our images
will load and their title will be set, along with the ability to click on each image and view the
full size original picture in all of it’s glory on the main Flickr Website. Awesome! In this
example, we load some images via AJAX, then click the first image to visit Flickr.
$.getXMLData();
So we can see that fetching JSON data is pretty exciting, and we were able to build a cool
application to fetch pictures from the Flickr API. jQuery also provides a way to fetch raw
XML data. The data returned will be an authentic XML document, not a string
representation of said data. Because of that, the standard DOM methods will work on this
data. Let’s see an example of how this particular method works.
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>jQuery Event Handling</title>
<link rel="stylesheet" href="bootstrap/css/bootstrap.css">
</head>
<body class="container">
<p></p>
<span id="click" class="btn btn-primary">Fetch XML Data!</span>
<p></p>
<div id="content" class="jumbotron">
</div>
<div class="alert">
</div>
<script src="jquery-1.11.1.js"></script>
<!-- Include all compiled plugins (below), or include individual files as needed -->
<script src="bootstrap/js/bootstrap.js"></script>
<!-- custom written js -->
<script src="tut.js"></script>
</body>
</html>
$(document).ready(function () {
function fetchXMLData() {
$.get('xmldata.xml', function (result) {
var website = result.getElementsByTagName('website')[0];
var about = result.getElementsByTagName('about')[0];
var val = 'What is this VegiBit you speak of? <b>' + website.firstChild.nodeValue + '</b> ' +
about.firstChild.nodeValue;
$('#content').append(val);
});
}
$('#click').click(function () {
fetchXMLData();
});
$.ajaxSetup({
// Disable caching of AJAX responses
cache: false
});
});
Running this method gives us this nice output as you can see.
function fetchXMLData() {
$.get('xmldata.xml', function (result) {
var website = result.getElementsByTagName('website')[0];
var about = result.getElementsByTagName('about')[0];
var val = 'What is this VegiBit you speak of? <b>' + website.firstChild.nodeValue + '</b> ' +
about.firstChild.nodeValue;
$('#content').append(val);
});
}
$('#click').click(function () {
fetchXMLData();
});
$.ajaxSetup({
// Disable caching of AJAX responses
cache: false
});
$(document).ajaxStart(function () {
$('<div class="alert alert-info">Ajax has started!</div>').insertAfter('#content');
});
$(document).ajaxStop(function () {
$('<div class="alert alert-danger">Ajax has ended!</div>').insertAfter('#content');
});
$(document).ajaxSend(function () {
$('<div class="alert alert-warning">Ajax is requesting the data
now!</div>').insertAfter('#content');
});
$(document).ajaxComplete(function () {
$('<div class="alert alert-success">The full AJAX life cycle is now
complete!</div>').insertAfter('#content');
});
$(document).ajaxSuccess(function () {
console.log("Looks like everything worked!");
});
});
• http://eloquent-javascript.net/
This is a pretty epic and incredible coverage of
the JavaScript language. In fact, the contents of this website are available as a book
in and of itself, though you can still read the tutorials for free at the website. Eloquent
JavaScript has become one of the ‘Go To’ resources for JavaScript today.
• https://developer-mozilla.org/-A_re-introduction_to_JavaScript
• http://www.js-therightway.org/
This website serves as a guide to people new to
JavaScript and experienced developers alike. The goal is to highlight best practices,
as you will find that there are so many different ways to solve the same problem. A
great resource to have in your toolkit.
• http://codecademy.com/-tracks/javascript
• https://developer-mozilla.org/-core_javascript_1.5_guide
Another gem from the Mozilla Developers
Network is their official reference guide to the JavaScript language. This resource is
perfectly organized into grammar and types, control flow and error handling, loops
and iteration, functions, expressions and operators, numbers and dates, text
formatting, arrays, keyed collections, objects, and much more.
• http://reference-designer.com/-tutorials/js/js_1.php
• http://adobe.com/-intro-to-javascript-for-the-total-beginner.html
Coming from the same folks that brought you the ever
popular Dreamweaver wysiwyg tool, is this Introduction to JavaScript for the total
beginner by Adobe. You’ll start with ‘Hello World’ and move on up to more advanced
topics like browser based calculations, working with variables, and dealing with
strings.
• http://lifehacker.com/-learn-to-code-the-full-beginners-guide
• https://www.khan-academy.org/-computing/computer-programming/programming
When Bill Gates says that one of his favorite
websites is Khan Academy, you know you’ve got a winner. This fun collection of
tutorials makes use of JavaScript and ProcessingJS to create your own animations
and drawings in the browser.
• http://code-tutsplus.com/-tutorials/the-best-way-to-learn-javascript
• http://microsoft-virtual-academy.com/-training-courses/javascript-fundamentals-for-absolute-
beginners
When you think about JavaScript, Microsoft is not
usually the first thing to pop into your mind. Well in this fantastic Channel 9 collection
of tutorials, you’ll be delighted with 21 episodes of learning from Bob Tabor, famed
for his excellent learnvisualstudio.net video tutorials website. Bob is a super talented
instructor, and he will inspire you with these great lessons on JavaScript.
• http://htmldog.com/-javascript/beginner/
• http://webmonkey.com/-javascript_tutorial/
Webmonkey from Wired has all kinds of great
Web Design and Web Development resources for all to enjoy. This particular one
focuses on the fun and excitement that can be had with JavaScript. Webmonkey
keenly observes that even though JavaScript is simple to work with, it is a complete,
powerful, and robust computer programming language.
• http://learn-jquery.com/-about-jquery/how-jquery-works/
• http://w3-schools.com/js/
W3Schools makes good use of their ‘Try it
Yourself’ feature to test basic snippets of JavaScript right in your web browser. At
this tutorial, they claim that JavaScript is easy to learn, and that you’ll go from
beginner to advanced in no time.
• http://tutorials-point.com/-javascript/
• http://code-project.com/-JavaScript-For-Beginners
The code project is another good resource for
leaning JavaScript at the beginning levels. This particular article comes from all the
way back in 2000, yet it still has some great concepts for you to learn.
• http://homeand-learn.co.uk/-javascript.html
• http://www.creative-bloq.com/-javascript/javascript-debugging-beginners
• http://javascript-roadtrip-codeschool.com/
• http://ejohn.org/-apps/learn/
• https://www.javascript.com/
Who could ask for a better domain name than
that? The fine folks at Code School put together this excellent resource for both
beginners and seasoned web developers alike. There is an entire JavaScript course
geared to towards newcomers to the language. In addition, there are news items,
tips, tricks, and tutorials about the latest happenings in the JS community regarding
the latest and greatest frameworks and libraries.
<div class="welcome"></div>
</body>
</html>
d3.select('.welcome').html('<h2>Welcome to D3</h2>');
How to select multiple elements and update the HTML with D3
<html>
<head>
<title>D3 JavaScript</title>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
</head>
<body>
<ul>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
</body>
</html>
<div id="circle"></div>
</body>
</html>
d3.select('#circle').append('svg')
.attr('height', 200)
.append('circle')
.style('fill', 'blue')
.attr('r', 50)
.attr('cx', 60)
.attr('cy', 60);
With just a small snippet of scripting, we are able to select a DOM element,
Pretty Cool!
append an SVG to it, and then draw a circle and make it blue using a sequence of chained
commands. This is the very basic idea of how D3 works. You’ll note that we can use basic
CSS to style the elements we create with D3. Any SVG element can be styled with
JavaScript and D3 or whatever CSS stylesheet you wish to use. You can simply choose
what makes sense to you when you are creating your graphics.
Interactivity With D3
The D3 library also provides ways to enable advanced interaction with the graphics on the
page. A built in physics engine is also part of D3 and it can account for things like friction,
bounce effects, force driven graphics, and gravity. Beyond this, D3 has an eventing system
much like jQuery and JavaScript itself to provide click and drag behavior, as well as
various touch behaviors.
• Selections
• Arrays
• Transitions
• Color
• Math
• Time
• SVG
• Scales
• Layouts
• Geography
• Geometry
• Behaviors
<body class="container">
<div class="main">
<h2>D3 JavaScript</h2>
</div>
</body>
</html>
We’d like to use the selector engine in D3 to fetch the li that contains jQuery, and update it
to say, “jQuery is cool”. Let’s try it out.
By using the nth-child selector, we easily specify the fourth item in the collection,
Excellent!
and update the value. Do note that this is not zero based! As programmers, we are used to
arrays and collections always starting at 0. With the nth-child selector, this is not the case.
It does in fact start at the number 1, so your counting will be easier. The nth-child selector
also has some really interesting features to further refine how you can select elements.
You can select all even or odd elements using :nth-child(even) and :nth-
child(odd) respectively. If you wanted to capture the 3rd element and all elements
thereafter, you could do so like this :nth-child(n+3). Maybe you would like to select every
third element, or every fifth element. Again, you could do that using :nth-
child(3n) and :nth-child(5n) respectively. It is a very useful selector to have a good
mastery of. Like anything else, simply test these out and try different approaches to solve
whatever selecting problem you may run into.
d3.append()
The d3.append() method works much like you would expect it to. Basically, you pass in to
the method what you would like to append to the selection. Common things to append are
HTML elements such as a span or div.
d3.insert()
The d3.insert() method is a little more granular than the d3.append(). With append, you
don’t really have control on where to place the element. With insert, if you’d like to place an
element inside of an unordered list for example, you can do that.
d3.text()
We’ve actually used d3.text() a few times already. As you have seen, it simply takes the
text that you pass into the method, and places that text in the element you have selected
on the page.
d3.html()
When you want to be able to insert entire chuncks of HTML instead of just plain text, you
can use the d3.html() method to do so.
d3.remove()
There will be times that you need to delete an element from the page. It is easy to do so
using the d3.remove() method.
Here is an example of using some of these D3 methods.
So this is pretty slick. What happens in this example is, we select the unordered list and
then append a div element to it. By chaining the d3.attr() method to this, we can set an
attribute and value for that attribute. As you can see we specify a class, then set the value
of that class to one contained in bootstrap. Recall we did include the bootstrap repository
via CDN in our sandbox test bed. Finally, we again chain another method. This time it is
the d3.html() method to place some HTML markup inside the newly appended div. We
didn’t make use of the d3.insert(), d3.text(), or d3.remove() yet, so let’s create another
example and do that now.
Lastly, if you wanted to remove all the li elements from the page, you could do so with style
and grace by using this snippet.
1 d3.selectAll('li').remove();
D3 DOM Manipulation
selection.attr()
By using the .attr() method, you can read, add, or modify any attribute in a selection. The
easiest way to see how this works is with a few examples.
Using .attr() to add a class
This approach is very useful if you already have a collection of CSS classes that you have
written, or if you would like to make use of 3rd party class names like those found in
Bootstrap or Foundation. Consider our example which has an unordered list of elements.
To assign a class name to all of those elements, we could do so just like this.
D3 Script to Run
d3.selectAll('li')
.attr('class','alert alert-warning');
note:In this example, the signature of .attr('class', 'classname') replaces any pre
existing class applied to the element. We can see this because in the original source,
each li has a class of .item. Once D3 does it’s work, we can now see that the .item class
is gone altogether and replaced with .alert alert-warning which gives us the nice effect
we see in the screenshot.
selection.classed()
The .classed() method runs a little differently. For example, we can use the signature
of .classed('classname', true) to basically turn a class on, without clobbering any
existing class. Let’s see how to do this.
D3 Script to Run
d3.selectAll('li')
.classed('alert alert-info', true);
As we can see, the .item class is left intact using this approach. The .classed() method
also can accept an object as it’s argument. By doing this we can turn multiple classes on
or off for a given element. Let’s select just one of the li items, turn off the .item class,
then turn on two Bootstrap classes to see the result.
Fantastic! Once again here is the source of before and after the script running.
source before D3 script:
<ul class="list list-unstyled">
<li class="item">JavaScript</li>
<li class="item">The DOM</li>
<li class="item">Scalable Vector Graphics</li>
<li class="item">jQuery</li>
<li class="item">Content Delivery Network</li>
</ul>
D3 Script to Run
d3.selectAll('li:nth-child(5)')
.classed({
'item': false,
'alert alert-danger': true,
'lead': true
});
Cool! This time when we run our D3 script, the first four items are left untouched. On the
fifth element however, we can see that the .item class has been turned off, the .alert
alert-danger class has been turned on, and the .lead class has also been turned on.
selection.style()
What about when you are not using predefined classes, but need to generate CSS styles
dynamically and on the fly so to speak? That is exactly what the .style() method is for, and
it has many, many use cases for working with D3. This is going to be the most flexible
approach that will give you the most control, especially for animation to effects so it pays to
be familiar with how it works. Here is an example in Firebug.
source before D3 script:
<ul class="list list-unstyled">
<li class="item">JavaScript</li>
<li class="item">The DOM</li>
<li class="item">Scalable Vector Graphics</li>
<li class="item">jQuery</li>
<li class="item">Content Delivery Network</li>
</ul>
D3 Script to Run
d3.selectAll('li:nth-child(3)')
.style({
'background': '#13afdf',
'margin': '7px',
'color': '#ffffff',
'padding': '11px'
});
With this approach, we can see there is no need to rely on a third party CSS
Very Slick!
framework or handwritten classes. We simply specify the styles we need and they are
applied inline. Even though we generally like to put our styles in their own dedicated
stylesheets, when styling dynamically in the DOM with real time applications like D3, inline
is the way it needs to happen. The other thing to consider is that this approach is going to
be the way we apply style to SVG, XML, and more.
D3 Script to Run
styles = [
{color: '#d6e9c6', width: 150},
{color: '#d9edf7', width: 200},
{color: '#fcf8e3', width: 250},
{color: '#f2dede', width: 300},
{color: '#bce8f1', width: 350}
];
d3.selectAll('li')
.data(styles)
.style({
'background': function (data) {
return data.color;
},
'width': function (data) {
return (data.width + 'px')
}
});
This particular example is a little bit more advanced because of the fact that we are
creating an array of objects, passing that array to the .data() method to bind the data
contained within, then we use the .style() method, and the value of the objects within use
anonymous functions to return the variable data. Say What? In essence, if you’re not
familiar with JavaScript, you’ll need to read up a bit on some of the JavaScript
Tutorials here and elsewhere on the web, since we’ll need a good understanding of it.
Especially important will be the idea of JavaScript functions being first class citizens in the
language.
Control HTML Attributes and Bind Data To The DOM With D3 JavaScript
Conclusion
Are we having fun yet? You bet we are! We’re starting to realize some of the power that
working with D3 in our pages affords us. Plug this code into your own sandbox and have a
play. Change the values of the data up in that final example. See what different kinds of
colors and widths you can come up with. It’s just the beginning, and we’ll cover lots more
in later tutorials.
You may have heard about SVG and thought, “Just What Are Scalable Vector
Graphics Anyway?” Well friend, you’ve come to the right place to learn!
Scalable Vector Graphics also goes by the common acronym, SVG, and it is a
vector image format based on the XML format. SVG was developed like most
other common Web Technologies by the W3C, or World Wide Web
Consortium. You’re likely familiar with SVG even if you dont’ realize it, since
many of the emoticons that have taken over our modern society are created in
an SVG format. Knowing what are Scalable Vector Graphics is an important pre
requisite for learning about the D3 JavaScript Library.
</svg>
</div>
Cool!Just like a circle we have a radius with the ellipse. In fact instead of having just one
radius, we actually have two in the ellipse. The first radius in the ellipse is rx and refers to
the radius on the horizontal plane of the ellipse. The ry radius of the ellipse is referring to
the vertical plane. If these two values are perfectly equal, then you have a perfect circle.
So all circles can be an ellipse, but not all ellipses can be a circle.
Let’s try rotating that ellipse on it’s side. This is easy to do by just swapping the rx and ry
values.
d3.select('#svghandle')
.append('svg')
.attr('width', 720)
.attr('height', 500)
.style('background', '#bce8f1')
.append('ellipse')
.attr('cx', 360)
.attr('cy', 220)
.attr('rx', 200)
.attr('ry', 100)
.style({'fill' : '#d9edf7', 'stroke' : '#31708f', 'stroke-width' : '25px'})
Polylines vs Polygons
Another thing worth mentioning when drawing scalable vector graphics is the difference
between a Polyline and a Polygon. We had used the polyline to draw a triangle early on in
this D3 Tutorial series. This is fine, but we can also use a Polygon for this application. In
fact, Polygon is probably the more technically correct element to use for shapes that are
self contained. So how do we differentiate this with a Polyline? Well, when you think of a
polyline, think of it like a set of steps and you are looking at them from the side. The steps
are one big line, which has many points. Let’s see an example of this concept.
d3.select('#svghandle')
.append('svg')
.attr('width', 720)
.attr('height', 500)
.style('background', '#bce8f1')
.append('polyline')
.attr('points', '100 0, 100 100, 200 100, 200 200, 300 200, 300 300, 400 300, 400 400, 500 400,
500 500, 600 500')
.style({'stroke' : '#31708f', 'stroke-width' : '12px'});
<div id="svghandle">
<svg width="720" height="500" style="background: #bce8f1">
<g id="original">
<ellipse rx="100" ry="200" cx="180" cy="240" style="fill: #d9edf7; stroke: #31708f;
stroke-width: 25px;"/>
</g>
<use xlink:href="#original" x="360" y="0"/>
</svg>
</div>
</div>
</div>
// the data that powers the bar chart, a simple array of numeric values
var chartdata = [40, 60, 80, 100, 70, 120, 100, 60, 70, 150, 120, 140];
// the width of each bar and the offset between each bar
barWidth = 40,
barOffset = 20;
d3.select('#bar-chart').append('svg')
.attr('width', width)
.attr('height', height)
.style('background', '#dff0d8')
.selectAll('rect').data(chartdata)
.enter().append('rect')
.style({'fill': '#3c763d', 'stroke': '#d6e9c6', 'stroke-width': '5'})
.attr('width', barWidth)
.attr('height', function (data) {
return data;
})
.attr('x', function (data, i) {
return i * (barWidth + barOffset);
})
.attr('y', function (data) {
return height - data;
});
Nice Work! That’s a decent looking bar chart for our first stab at it. There are actually a few
tricky things to be aware of here when understanding how D3 constructs the data here.
Everything may look pretty straightforward by simply reading the code above, right up until
you reach the point of selecting rectangles that are not yet there! Observe this list.
• selection.selectAll()
• selection.data()
• selection.enter()
• selection.append()
To really understand how all of this works, read the documentation for all four links above.
In addition, Mike Bostock the genius behind D3, wrote this tutorial to help understand how
these methods work with each other to create the magic that D3 does. This helps to piece
together the concept of being able to select elements that do not yet exist in the DOM, and
then programmatically create said elements and update them with dynamic data like in this
basic bar chart example.
Change The Data Powering The Bar Chart
Just to show that indeed the chart is rendering based on the values provided in
the chartdata variable, we can change up the values in that array and observe the
updated bar chart that gets created.
var chartdata = [10, 20, 30, 40, 50, 60, 75, 90, 110, 130, 150, 190];
var chartdata = [170, 50, 40, 30, 60, 50, 85, 80, 120, 120, 160, 150];
• chartdata an array of numeric values that power the length of each bar
• height a single numeric value containing the height of the SVG
• width a single numeric value holding the width of the SVG
• barWidth a single numeric value holding the width of each bar
• barOffset a single numeric value holding the space between bars
The first part of this is pretty easy. It follows the same format we have been using for the
past several tutorials.
d3.select('#bar-chart').append('svg')
.attr('width', width)
.attr('height', height)
.style('background', '#dff0d8')
This grabs the div with the id of #bar-chart and simply appends an SVG to it, setting the
width and height to the values provided in our variables listed above. We also give the bar
chart a pleasing background color in this step. What comes next however is where your
mind breaks a little when it realizes you shouldn’t be able to select elements not yet
created.
.selectAll('rect').data(chartdata)
.enter().append('rect')
In simple English, the above snippet says to iterate over all of the values contained in
the chartdataarray and for each piece of data, append a rectangle tag associated with it.
Once all pieces of data have been iterated over and each <rect> has been appended, then
select them all. So in a sense, you would almost expect the .selectAll() method to be
last, but this is how we write this declarative approach in D3. Declarative means to just
declare what you want, not how to go about getting it. Another example of the declarative
style is found in how SQL works.
The next snippet of JavaScript just a touch more advanced. Let’s go through it.
.style({'fill': '#3c763d', 'stroke': '#d6e9c6', 'stroke-width': '5'})
.attr('width', barWidth)
.attr('height', function (data) {
return data;
})
.attr('x', function (data, i) {
return i * (barWidth + barOffset);
})
.attr('y', function (data) {
return height - data;
})
If you’re still fairly new to JavaScript, and the above looks like hieroglyphics to you – fear
not. In simple English, all that is happening here is we are applying a style to each
rectangle, or bar, as it gets inserted into the SVG area. In addition, we set four attributes
on each bar. It makes sense that each bar needs a width, a height, an x coordinate, and
a y coordinate. Recall, the x coordinate determines where each bar is located on the SVG
area from left to right while the y coordinate determines where the bar is placed in terms of
top and bottom on the SVG area. In fact, suppose we did not include the ycoordinate, what
would happen? Well remember that the y coordinate is determined from the top down, so
without it, we’d only have the left/right location data. Observe.
var chartdata = [10, 20, 30, 40, 50, 60, 75, 90, 110, 130, 150, 190];
d3.select('#bar-chart').append('svg')
.attr('width', width)
.attr('height', height)
.style('background', '#dff0d8')
.selectAll('rect').data(chartdata)
.enter().append('rect')
.style({'fill': '#3c763d', 'stroke': '#d6e9c6', 'stroke-width': '5'})
.attr('width', barWidth)
.attr('height', function (data) {
return data;
})
.attr('x', function (data, i) {
return i * (barWidth + barOffset);
});
Interesting. Without specifying the y coordinate, it looks like everything starts from the top
down. Therefore, in order to get the right value for the y coordinate, we need to calculate
the difference between the height of the SVG container, and the height (or length if you
will) of the bar. The best way to cement this home is to plug the code into your own
sandbox and simply hack away at the values and observe the results in the browser. One
other trick to remember what x and y refer to is to think, “x to the left, y to the sky.” This
helps to remember the fact that x is the horizontal line, and y is the vertical line. Why are
those two always so easy to mix up?!
• d3.scale.linear()
• d3.scale.linear().domain()
• d3.scale.linear().range()
var chartdata = [40, 60, 80, 100, 70, 120, 100, 60, 70, 150, 120, 140];
d3.select('#bar-chart').append('svg')
.attr('width', width)
.attr('height', height)
.style('background', '#dff0d8')
.selectAll('rect').data(chartdata)
.enter().append('rect')
.style({'fill': '#3c763d', 'stroke': '#d6e9c6', 'stroke-width': '5'})
.attr('width', barWidth)
.attr('height', function (data) {
return yScale(data);
})
.attr('x', function (data, i) {
return i * (barWidth + barOffset);
})
.attr('y', function (data) {
return height - yScale(data);
});
Very nice – we can see that now, the bar with the largest value takes up the entire range of
vertical space on the chart, while the other bars scale in relation to this. Excellent. This is a
bit more efficient and elegant than the hard coded y axis version.
• d3.scale.ordinal()
• d3.scale.ordinal().domain()
• d3.scale.ordinal().rangeBands()
var chartdata = [40, 60, 80, 100, 70, 120, 100, 60, 70, 150, 120, 140,
140, 120, 150, 70, 60, 100, 120, 70, 100, 80, 60, 40];
d3.select('#bar-chart').append('svg')
.attr('width', width)
.attr('height', height)
.style('background', '#dff0d8')
.selectAll('rect').data(chartdata)
.enter().append('rect')
.style({'fill': '#3c763d', 'stroke': '#d6e9c6', 'stroke-width': '5'})
.attr('width', xScale.rangeBand())
.attr('height', function (data) {
return yScale(data);
})
.attr('x', function (data, i) {
return xScale(i);
})
.attr('y', function (data) {
return height - yScale(data);
});
Using Colors With Linear Scaling
If you would like to make your chart more visually appealing, you can so do by applying
colors to the bars instead of just one solid color. Let’s see how to use the linear scale
method to do this now.
var chartdata = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120,
135, 150, 165, 180, 200, 220, 240, 270, 300, 330, 370, 410];
d3.select('#bar-chart').append('svg')
.attr('width', width)
.attr('height', height)
.style('background', '#dff0d8')
.selectAll('rect').data(chartdata)
.enter().append('rect')
.style({'fill': function(data,i){return colors(i);}, 'stroke': '#31708f', 'stroke-width': '5'})
.attr('width', xScale.rangeBand())
.attr('height', function (data) {
return yScale(data);
})
.attr('x', function (data, i) {
return xScale(i);
})
.attr('y', function (data) {
return height - yScale(data);
});
var dynamicColor;
d3.select('#bar-chart').append('svg')
.attr('width', width)
.attr('height', height)
.style('background', '#bce8f1')
.selectAll('rect').data(chartdata)
.enter().append('rect')
.style({'fill': function(data,i){return colors(i);}, 'stroke': '#31708f', 'stroke-width': '5'})
.attr('width', xScale.rangeBand())
.attr('height', function (data) {
return yScale(data);
})
.attr('x', function (data, i) {
return xScale(i);
})
.attr('y', function (data) {
return height - yScale(data);
})
.on('mouseover', function(data) {
dynamicColor = this.style.fill;
d3.select(this)
.style('fill', '#3c763d')
})
.on('mouseout', function(data) {
d3.select(this)
.style('fill', dynamicColor)
});
Note: Move your mouse over this chart! (visit Vegibit.com to see in action)
Applying D3 Transitions
D3 has an incredible ability to create what is called a Transition, which means to apply
operators and attributes in a smooth and consistent way over time, rather than
immediately. This is used to create visually stunning effects and animation. We’ll use the
following four methods.
• d3.transition()
• transition.delay()
• transition.duration()
• d3.ease()
To see just a simple transition in action, click the button here. (visit Vegibit.com to see in
action)
Click To Apply D3 Transition
Here is the code to recreate the transition effect.
var chartdata = [410, 370, 330, 270, 240, 220, 200, 180, 165, 150, 135, 130,
135, 150, 165, 180, 200, 220, 240, 270, 300, 330, 370, 410];
var dynamicColor;
awesome.transition()
.attr('height', function (data) {
return yScale(data);
})
.attr('y', function (data) {
return height - yScale(data);
})
.delay(function (data, i) {
return i * 20;
})
.duration(2000)
.ease('elastic');
Here is the code for the final iteration of our bar chart.
var chartdata = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120,
135, 150, 165, 180, 200, 220, 240, 270, 300, 330, 370, 410];
var margin = {top: 30, right: 10, bottom: 30, left: 50}
var dynamicColor;
var yScale = d3.scale.linear()
.domain([0, d3.max(chartdata)])
.range([0, height])
awesome.transition()
.attr('height', function (data) {
return yScale(data);
})
.attr('y', function (data) {
return height - yScale(data);
})
.delay(function (data, i) {
return i * 20;
})
.duration(2000)
.ease('elastic')
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.14/vue.min.js"></script>
<script src="vue.js"></script>
</body>
</html>
With this configuration we have access to all of the features of Vue.js via a content delivery
network, as well as some css styling via the bootstrap framework, also from a CDN. This
way, it is simple to build out our code playground in about 10 seconds.
Vue.js instance
new Vue({
el: '#todo',
data: {
hello: 'This is a two way data bind'
}
})
Anything that gets typed into the input is immediately updated in the dom. Very cool.
v-on
The v-on directive is used to add an event listener to the element. For example, when
building a Todo application, we can use the v-on directive in a form like so.
<form v-on:submit="addTodo">
This will add an event listener for the submit action on a form.
v-model
The v-model directive is used to create a two way binding to a form input element. It can
be used on <textarea>, <select>, and <input> tags as needed.
An example in a Todo app might be like so.
<input v-model="newTodo"
v-el="newTodo"
class="form-control"
placeholder="What do you need to do?">
</input>
v-el
The v-el directive registers a reference to a dom element to the corresponding Vue
instance. We can see a use case in the prior snippet where we demonstrate the v-model.
v-show
The v-show directive is used to set off transitions. In other words, if you take action on an
element in the dom which interacts with a Vue instance, a different portion of the dom can
be updated in real time. For the Todo app, we can show items we finish with something
like this.
<div v-show="pending.length">
<h1>todo ({{ pending.length }})</h1>
<ol class="list-group">
<li v-for="todo in pending"
class="list-group-item"
>
<span v-on:dblclick="editTodo(todo)">{{ todo.body }}</span>
v-repeat
v-for is often used to display a list. It is populated by an array of objects in the ViewModel.
Each object in the array gets a child Vue instance created. In the snippet above, you can
see how by combining v-show with v-for, we can output lists of items in real time.
The Vue.js directives are automatically bound to a property on your Vue instance. When
the value of the underlying property changes, so to does the view by way of
an update() function. Learn about all of the Vue.js directives right at the official
documentation.
el: '#todos',
data: {
},
computed: {
},
methods: {
});
We can see that this is an object of objects. el is the Vue instance in the dom represented
by a string (css selector). data is an object and refers to the data object of the Vue
instance, for which we can import and export information to and from. computed is a special
object which holds properties to be mixed in to the Vue instance. The this keyword is
bound to the Vue instance. methods are where all of your functions get defined, and they
can be called from the directive, or directly on the VM instance.
<form v-on:submit="addTodo">
<div class="form-group">
<input v-model="newTodo"
class="form-control"
placeholder="What do you want to do?">
</input>
</div>
<div>
<h1>Things to do</h1>
<ol class="list-group">
<li v-for="todo in todos" class="list-group-item">
{{ todo.body }}
</li>
</ol>
</div>
</div>
</div>
Vue.js code
new Vue({
// the Vue Instance
el: '#todos',
newTodo: ''
},
methods: {
// function declarations
addTodo: function (e) {
this.todos.push({
body: this.newTodo,
completed: false
});
// simply set the form input field to an empty string
// after we add a todo item
this.newTodo = '';
}
}
});
This is pretty readable. Where you can see the button, it simply says when you click this
button, call the deleteTodo function and pass in the current iteration of the todo during this
looping process of v-repeat. Now just add the deleteTodo function to our method object
and we should be good to go.
// the deleteTodo function
deleteTodo: function(todo) {
this.todos.$remove(todo);
}
We go get a drink of water, click the delete button, and voila – it is gone.
<ol class="list-group">
<li v-for="todo in pending" class="list-group-item">
{{ todo.body }}
<button v-on:click="deleteTodo(todo)" class="btn btn-default"><span class="glyphicon
glyphicon-remove" aria-hidden="true"></span></button>
<button v-on:click="editTodo(todo)" class="btn btn-default"><span class="glyphicon
glyphicon-edit" aria-hidden="true"></span></button>
<button v-on:click="markComplete(todo)" class="btn btn-default"><span class="glyphicon
glyphicon-ok" aria-hidden="true"></span></button>
</li>
</ol>
</div>
<div v-if="finished.length">
<h2>Completed ({{finished.length}})</h2>
<ol class="list-group">
<li v-for="todo in finished" class="list-group-item">
{{ todo.body }}
<button v-on:click="deleteTodo(todo)" class="btn btn-default"><span class="glyphicon
glyphicon-minus-sign" aria-hidden="true"></span></button>
</li>
</ol>
In the snippet above, you can see that we are referencing a pending and finished property
in our code. Let’s see what this corresponds to in the JavaScript side.
new Vue({
// the Vue Instance
el: '#todos',
newTodo: '',
filters: {
notDone: function(todo) {
return ! todo.completed;
},
completed: function(todo) {
return todo.completed;
}
}
},
computed: {
finished: function () {
return this.todos.filter(this.filters.completed);
},
pending: function () {
return this.todos.filter(this.filters.notDone);
}
},
});
This function will mark a pending item as finished, and our filters will move the todo item
from the pending list to the finished list in the corresponding HTML.
Marking items as complete
Finally, we can add two functions to either complete all todo items, which will move them
from the pending to the finished list, in addition to adding a function to mark all finished
items as complete and remove them from the finished list.
// mark all items as complete by looping over them
completeAll: function () {
this.todos.forEach(function (todo) {
todo.completed = true;
});
},
// clear all completed items
clearCompleted: function () {
this.todos = this.todos.filter(this.filters.notDone);
}
Vue.js Tutorial
html
<div id="myvueinstance" class="container">
</div>
js
var viewmodel = new Vue({
el: '#myvueinstance'
});
You have created your first Vue instance. What this means is that this div
Congratulations!
with the id of #myvueinstance, as well as any other elements it contains, now has access to
all of the magic that your Vue instance can provide. This div is now Vueified if you will.
html
<div id="myvueinstance" class="container">
<div class="row">UI element</div>
<input type="text" v-model="textinput" class="form-control">
<p> </p>
js
var viewmodel = new Vue({
el: '#myvueinstance',
data: {
textinput: 'Too hot, hot damn.'
}
});
As you can see, the data is updated in real time in both directions.
# Displaying Lists with Vue.js
How can we loop through an array of data and output each item one at a time in Vue.js?
Well, just like PHP has a foreach construct, and JavaScript has a for(in), Vue.js uses the v-
for directive to easily loop over data, and take action on it. It’s so simple, it’s almost
deceiving at first. First, we’ll set up an array of JavaScript libraries to work with in our Vue
Instance.
js
var viewmodel = new Vue({
el: '#myvueinstance',
data: {
libraries: ['angular.js', 'd3', 'node', 'jquery']
}
});
note: Pay attention to the syntax we are using with the v-for directive. When working with
loops, you might be used to making sure you keep your singulars and plurals in order so
you can more easily reference the desired element on each iteration of the loop. In PHP, it
follows the notion of foreach (plural as singular) and in JavaScript it follows something like
for (singular in plural).
<li v-for=”library in libraries” class=”active”><a href=”#”>{{ library }}</a></li>
I like to read this snippet as follows: For each library in libraries, echo out one library one at
a time. In fact, this snippet does give us the desired result as you can see here.
UI List Element
Like everything in programming, there are many more ways to do the same thing we just
did here. In the efforts of brevity, we’ll move forward for now. Do check out the official docs
if you are a “need to know everything” type of person.
js
var viewmodel = new Vue({
el: '#myvueinstance',
data: {
libraries: ['angular.js', 'd3', 'node', 'jquery'],
newlibrary: ''
},
methods: {
addLibrary: function () {
this.libraries.push(this.newlibrary);
this.newlibrary = '';
},
deleteLibraries: function () {
this.libraries = [];
}
}
});
html
<div id="myvueinstance" class="container">
<div class="row">UI List Element</div>
<p> </p>
<input class="form-control" type="text" placeholder="Type the library name here, then click the
button below." v-model="newlibrary">
<button class="btn btn-info" v-on:click="addLibrary">Click to add library</button>
<button class="btn btn-danger" v-on:click="deleteLibraries">Click to delete all
libraries</button>
<p> </p>
jquery
$("#element").click(function () {
alert("you just clicked this");
});
Vue js
methods: {
myfunction: function () {
alert('you just clicked this');
}
}
If you follow this general outline, you’ll find you can implement any type of event listener
and associated handlers in a clean and simple way with Vuejs.
html
<div id="myvueinstance" class="container">
<div class="row">UI List Element</div>
<tbody>
<tr v-for="framework in frameworks | filterBy filterkey | orderBy sortparam order">
<td>{{ framework.id }}</td>
<td>{{ framework.framework }}</td>
</tr>
</tbody>
</table>
</div>
js
var viewmodel = new Vue({
el: '#myvueinstance',
data: {
sortparam: '',
fitlerkey: '',
order: 1,
frameworks: [
{id: '001', framework: 'angular'},
{id: '002', framework: 'd3'},
{id: '003', framework: 'node'},
{id: '004', framework: 'jquery'},
{id: '005', framework: 'reveal.js'},
{id: '006', framework: 'impress.js'},
{id: '007', framework: 'backbone.js'},
{id: '008', framework: 'meteor.js'},
{id: '009', framework: 'express'},
{id: '010', framework: 'moment'},
{id: '011', framework: 'underscore'},
{id: '012', framework: 'gulp'},
{id: '013', framework: 'react'},
{id: '014', framework: 'ghost'},
{id: '015', framework: 'sweetalert'},
{id: '016', framework: 'select2'},
]
},
methods: {
sortvia: function (sortparam, order) {
this.order = this.order * -1;
this.sortparam = sortparam;
}
}
});
Try it! Click id or Framework to sort by that column. Enter a search in the text field to filter.
html
<div id="myvueinstance" class="container">
<h4>{{ string | upper }} </h4>
</div>
In the snippet above, we output a string two times. The first time, we pipe it to an upper
filter. The second time, we pipe it to a lower filter. Let’s see how we created these in our
JavaScript.
js
var viewmodel = new Vue({
el: '#myvueinstance',
data:{
string: 'Custom Filters'
},
filters: {
upper: function(value) {
return value.toUpperCase();
},
lower: function(value) {
return value.toLowerCase();
}
}
});
Upon running this in the browser, we see both instances work great as CUSTOM
FILTERS and custom filters is output to the screen.
html
<div id="anotherdiv" class="container">
js
var anothermodel = new Vue({
el: '#anotherdiv',
data:{
string: 'Spooky action from a distance.'
}
});
See how the first two lines are being operated on by the upper and lower filters? Notice
that lines three and four are simply outputting the string as if they have ignored the upper
and lower filters. In fact, they are ignoring those filters because they are bound to the first
Vue instance and not the second. How can we use those filters on both instances? We can
get our spooky action at a distance by making them global of course! Let’s change up our
JavaScript to this:
Vue.filter('upper', function (value) {
return value.toUpperCase();
});
data: {
string: 'Custom Filters'
}
});
data: {
string: 'Spooky action from a distance.'
}
});
By making our upper and lower filters global, and removing them from the filters object of
the first instance, we can now make use of them on any Vue instance in our html.
Reloading our browser shows that this is in fact the case.
CUSTOM FILTERS
custom filters
SPOOKY ACTION FROM A DISTANCE.
spooky action from a distance.
Those are the basics of filters in Vue.js, but do go ahead and hit up the filters
documentation for more features like two way filters and dynamic arguments.
# Vue.js Components
Components are a really slick way of creating your own html elements for reuse. That is to
say, you can define a custom html tag, and implement what that tag does in Vue.js for you.
As an example, let’s try to make an <alert> tag we can use.
js
Vue.component('alert', {
template: '<div class="alert alert-success" role="alert"><b>Smashing!</b> Nice work.</div>'
});
html
<div id="myvueinstance" class="container">
<alert></alert>
</div>
With just this small snippet of code, we now have a reusable alert tag, as you can see
here.
Smashing! Nice work.
Wow. I’m sure you can see the power there. Imagine the things you could do with this!
# Vue.js Component Props
If you’re excited with what your own components can do for you, you’re about to jump for
joy when you see what component props can do for you! In the example above, we
created our very own tag, and we can use it anywhere we might need to produce an alert.
At the moment, it is hard coded so to speak. What about different alert types, with different
messages? How can we do this? I give you: Props!
js
Vue.component('alert', {
template: '<div class="alert alert-{{ type }}" role="alert"><b>{{ bold }}</b> {{ msg }}</div>'
});
html
<div id="myvueinstance" class="container">
</div>
Note that the props property holds an array of strings. Those strings become attributes on
your custom html element. You then simply provide whatever you want to those attributes
in your html, and witness the magic happen.
Greetings. This is some information.
Slow down. You might crash.
Oh no! The program just crashed!
Rock Out with your Props out!
Cool!With a good dose of imagination, you could create some really amazing components
for use in any of your projects.
# Custom Directives with Vue.js
As we have learned, directives in Vue.js are the custom attributes that begin with v- in the
html markup. In addition to all of the standard directives that perform various operations,
you can use Vue.js to create custom directives. By creating custom directives you can, in a
sense, program Vue to map data changes to dom behavior according to your liking.
As an example, we will create a new v-twitter custom directive, that when clicked, will
open a window to share an article on twitter.
js
Vue.directive('twitter', function (message) {
this.el.addEventListener('click', function () {
html
<div id="myvueinstance" class="container">
<button v-twitter="'You gotta see how cool Vue.js is!'" class="btn btn-info">Share this on
Twitter</button>
</div>
Further Reading
Vue.js is really in it’s infancy, but developers are finding it to be very user friendly and
powerful at the same time. Learn more about Vue with these great resources.
• Vue.js: a (re)introduction
• Vue.js Official Blog
1. That JS Dude
http://thatjsdude.com/
That JS Dude bills itself as the easiest and funniest way to understand JavaScript. At that
JS Dude, you will learn how to better understand things
like this, scope, hoisting, closure, inheritance, bind, call, apply, prototype, event
delegation, dom, timers and other concepts that people sometimes find confusing. That JS
Dude has various sections as well so you can drill down on the information that you are
looking to better understand. There are sections for the console, javascript this keyword,
scope and closure, arrays, interview questions, and even some tutorials about the popular
React JavaScript Framework.
2. ES6 Katas
http://es6katas.org/
Katas are a form of training exercises in order to gain better mastery of a skill. The word
has ties to the martial arts, so if you are looking for Bruce Lee style focus and mastery then
you are going to love ES6 Katas. At ES6 Katas, you can learn the new flavor of JavaScript
one step at a time. The topics include Array, Class, Destructuring, Generator, Map,
Reflect, Set, Iterator, Template Strings, String, Symbol, Arrow functions, Block Scope,
Rest operator, Spread Operator, Modules, Object, and Unicode. You can also subscribe to
an RSS feed via tddbin which makes it super convenient to keep up with daily exercises.
3. Exploring ES6
http://exploringjs.com/
Exploring ES6 is a book by Dr Axel Rauschmayer. Axel is writer for the popular
blog 2ality.com where he has frequently updated content about JavaScript, mobile
computing, all forms of web development, and more. The blog has been online since 2005,
so there is a wealth of good information there. His book is great for people that are already
familiar with JavaScript, but need to come to grips with the new features of ES6 and how
to best make use of them. There is a free online version of the book, however if you would
like to support his work you can also opt to buy the ebook version for a small fee.
4. Speaking JS
http://speakingjs.com/es5/
This resource is another resource by Dr Axel Rauschmayer and it focuses on JavaScript
ES5. The preface gives us a good overview of what to expect from the book, as well as
some perspective on JavaScript itself. Alex talks about how thanks to the Web, you
absolutely can not avoid JavaScript, even if you are not keen to the quirks that it has. The
book is broken down into four parts which include Basic JavaScript, The History of
JavaScript, A reference type section, and finally some best practices to follow and
advanced techniques.
5. JavaScript.info
http://javascript.info/
Learn about JavaScript: from the Ground to Closures, Document and Events, Object
Oriented Programming, Timing, Frames and windows, Regular expressions in JavaScript,
and Advanced and Extra stuff.
9. JavaScript Essentials
https://medium.com/javascript-scene/learn-javascript-b631a4af11f2
Eric Elliot is a master JavaScript programmer with an interest in viral apps, film,
photography, music, education, and entrepreneurialism. In this article, Eric makes the case
for JavaScript. Why? Because JavaScript is the platform language of the Web. In fact,
using JavaScript will enable you to create applications capable of running on any platform
you want whether that be basic websites, advanced web applications, native applications,
or mobile computing. JavaScript is on all of these platforms. Eric puts a focus on learning
what he calls the pillars of JavaScript, and those would be Functional Programming and
Prototype based inheritance.
15. JavaScript.com
https://www.javascript.com/
This website is brought to us by Code School as a free resource for all JavaScript
developers. Not only is JavaScript powerful and advanced for professional programmers, it
is also a great programming language for beginners as well. The team from Code School
has created a round up of their favorite JavaScript resources, and built an entire tutorial
based course around them. Community members also contribute to the website, and in
addition to helping developers get up to speed, it is a goal to also cater to more advanced
programmers with up to date news, frameworks, and libraries.
26. JSBooks
http://jsbooks.revolunet.com/
JSBooks is so incredible and epic, that we had to give it it’s own numbered bullet point in
our awesome list of javascript learning tutorials. JSBooks is a website created
by revolunet, expert consultants and developers for modern web applications on desktop
and mobile platforms. Visit their JSBooks resource to filter by Beginning, Intermediate, and
Advanced topics, so that you can drill right down to the level of learning you are most
interested in, or ready for.
Upgrading VueJS
In this post we’ll take a look at upgrading VueJS. We have a cool tutorial about
Vue.js but alas, JavaScript moves in Internet time – which means some of the
information has become dated already. Well fear not! The tutorial is getting
updated, and this post is a chronicle of what you might encounter when
completing your own migration path from an earlier version to 1.0.0 or a release
candidate of 1.0.0. We will be using 1.0.0-rc2.
Displaying Lists
We now take a look at displaying lists with Vue using the latest build and we encounter our
first few errors. Let’s see.
We have some very helpful warnings in the console that will guide us on how to resolve
our issues.
Let’s update our code to fix the problems. The syntax for v-repeat has changed to v-for. In
order to get our code work properly, we need to make this change.
Old
<ul class="nav nav-pills">
<li v-repeat="library: libraries" class="active"><a href="#">{{ library }}</a></li>
</ul>
New
<ul class="nav nav-pills">
<li v-for="library in libraries" class="active"><a href="#">{{ library }}</a></li>
</ul>
With that quick update, everything is now working again.
Moving further along we had added some functionality to add or delete a JavaScript
Library. It looks like this one does cause some errors.
• [Vue warn]: Invalid expression. Generated function body:
scope.click:scope.addLibrary
• TypeError: expParser.parse(…) is undefined
var fn = expParser.parse(expression).get
• [Vue warn]: You are setting a non-existent path “newlibrary” on a vm instance.
Consider pre-initializing the property with the “data” option for more reliable reactivity
and better performance.
Lets see if we can figure out how to fix these… (hacking in the sandbox) … turns out this is
a pretty easy fix.
Old
<input class="form-control" type="text" placeholder="Type the library name here, then click the
button below." v-model="newlibrary">
<button class="btn btn-info" v-on="click: addLibrary">Click to add library</button>
<button class="btn btn-danger" v-on="click: deleteLibraries">Click to delete all libraries</button>
New
<input class="form-control" type="text" placeholder="Type the library name here, then click the
button below." v-model="newlibrary">
<button class="btn btn-info" v-on:click="addLibrary">Click to add library</button>
<button class="btn btn-danger" v-on:click="deleteLibraries">Click to delete all libraries</button>
This is another welcome change. It does in fact appear much more readable to me. Now
we can see that the event action is moved out of the attribute value and attached to the v-
on directive. With regard to that third error listed above, we simply add the newlibrary
property to the data object like the warning asked and it did in fact make the error go away.
data: {
libraries: ['angular.js', 'd3', 'node', 'jquery'],
newlibrary: ''
},
Old
html
<div id="myvueinstance" class="container">
<div class="row">UI List Element</div>
<tbody>
<tr v-repeat="frameworks | filterBy filterkey | orderBy sortparam reverse">
<td>{{ id }}</td>
<td>{{ framework }}</td>
</tr>
</tbody>
</table>
</div>
js
var viewmodel = new Vue({
el: '#myvueinstance',
data: {
sortparam: '',
reverse: false,
fitlerkey: '',
frameworks: [
{id: '001', framework: 'angular'},
{id: '002', framework: 'd3'},
{id: '003', framework: 'node'},
{id: '004', framework: 'jquery'},
{id: '005', framework: 'reveal.js'},
{id: '006', framework: 'impress.js'},
{id: '007', framework: 'backbone.js'},
{id: '008', framework: 'meteor.js'},
{id: '009', framework: 'express'},
{id: '010', framework: 'moment'},
{id: '011', framework: 'underscore'},
{id: '012', framework: 'gulp'},
{id: '013', framework: 'react'},
{id: '014', framework: 'ghost'},
{id: '015', framework: 'sweetalert'},
{id: '016', framework: 'select2'},
]
},
methods: {
sortvia: function (sortparam) {
this.reverse = (this.sortparam == sortparam) ? !this.reverse : false;
this.sortparam = sortparam;
}
}
});
New
html
<div id="myvueinstance" class="container">
<div class="row">UI List Element</div>
<input type="text" class="form-control" v-model="filterkey">
<tbody>
<tr v-for="framework in frameworks | filterBy filterkey | orderBy sortparam order">
<td>{{ framework.id }}</td>
<td>{{ framework.framework }}</td>
</tr>
</tbody>
</table>
</div>
js
var viewmodel = new Vue({
el: '#myvueinstance',
data: {
sortparam: '',
fitlerkey: '',
order: 1,
frameworks: [
{id: '001', framework: 'angular'},
{id: '002', framework: 'd3'},
{id: '003', framework: 'node'},
{id: '004', framework: 'jquery'},
{id: '005', framework: 'reveal.js'},
{id: '006', framework: 'impress.js'},
{id: '007', framework: 'backbone.js'},
{id: '008', framework: 'meteor.js'},
{id: '009', framework: 'express'},
{id: '010', framework: 'moment'},
{id: '011', framework: 'underscore'},
{id: '012', framework: 'gulp'},
{id: '013', framework: 'react'},
{id: '014', framework: 'ghost'},
{id: '015', framework: 'sweetalert'},
{id: '016', framework: 'select2'},
]
},
methods: {
sortvia: function (sortparam, order) {
this.order = this.order * -1;
this.sortparam = sortparam;
}
}
});
With the updated code, all errors are gone and the test subject is functional again. Do the
old “stare and compare” of the old versus new code above to see if you can spot what
changed. Then read up on filterBy and orderBy and you’ll be good to go.
Custom Filters
The code which was used for the custom filters section of the tutorial seems to be working
just fine with no errors. A quick scan seems to indicate these work as they did before, but
it’s worth reading up of course on the latest docs.
Components
The Components code is working on the latest build of Vue.js, so that is good.
Component Props
Component Props also seem to be working nicely with no modifications to the original
markup.
Custom Directives
Lastly, Custom Directives do appear to work just fine as well with the latest VueJS code.
In this post we will install NodeJS on Windows. We like to make use of virtual
machines to create development environments so that we can “build the world”
so to speak when creating new applications and websites. This is certainly one
of the best ways to tackle workflow. Sometimes however, we just want a quick
way to kick the tires, or try out a few simple commands on a console and we
don’t want to wait for the entire process of a VM to boot up and provision. For
PHP we use a tool like Wamp. For NodeJS we will simply install it on the
machine using the official Node Installer.
Visit NodeJS.org
First off, open up a browser and navigate to https://nodejs.org. The site will detect what
type of operating system you are using, and will present you with the download which you
need. In our case, we are on Windows, so we are presented with this friendly option.
Click Download for Windows
We want to install the software, so let’s go ahead and click on the Download for Windows
button to begin the download. You will be prompted to save a Windows Installer Package,
in our case it is the file node-v4.2.1-x64.msi. You have the option to Save File or Cancel.
Let’s go ahead and save that file.
You will see the Welcome to the Node.js Setup Wizard appear.
Enable the check box to accept the terms in the License Agreement.
Choose a custom location or click Next to install.
We will accept the default destination folder and click Next.
Custom Setup
We will accept the default features to be installed by selecting Next. We are prompted that
this requires 12MB of space on the hard drive. 2 of 2 subfeatures are selected which
require 16KB on the hard drive.
NodeJS Is Installed!
Typically the first thing people do is to check the versions of Node and NPM which are
installed. We will do this from a standard Windows Command Prompt. To open a
command prompt, simply type cmd into your Windows Search programs and files search
box, then hit the enter key.
Now, you can type node -v and hit enter. Also type npm -v and hit enter. Our output shows
us v4.2.1 of NodeJS and 2.14.7 of NPM.
Believe it or not, you have just created your very first NodeJS application!
• Install Learnyounode
Getting Ready
• 1Hello World
• 2Baby Steps
• 3My First I/O
• 4My First Async I/O
• 5Filtered Ls
• 6Make It Modular
• 7Http Client
• 8Http Collect
• 9Juggling Async
• 10Time Server
• 11Http File Server
• 12Http Uppercaser
• 13Http Json API Server
• The TakeawayBest Way To Learn Node Summary
1. Hello World
We will waste no time, for we want to dig right in to the best way to learn node.js. From the
table of contents menu, we will in fact choose the first challenge: Hello World.
We can see we have some instructions for our task. In fact we need to create a
Cool!
program that writes the text of “HELLO WORLD” to the console. Let’s see if we can do it.
We will create a file named program.js in the directory we are running our learnyounode
session from.
program.js
console.log("HELLO WORLD");
This is not a very big program, but I do think it is what we need! As we can see in the
instructions of learnyounode, we can verify a program by simply typing:
learnyounode verify program.js
On typing this message in our console, we find profit!
How cool is that?! We are presented of the actual results versus the expected results, a
pass or fail indicator, and the official solution to the problem. We are also presented with
the number of challenges we have left. This is a very slick program indeed.
We should always review the methods used for each example and for this one we
have console.log().
2. Baby Steps
As indicated in the last section, we again type learnyounode to bring us back to the main
menu.
The program keeps track of our progress and we can see that HELLO WORLD is
completed and we are now at BABY STEPS. Let us try to complete some baby steps.
Whoa. We are not in hello world land anymore. In this step, we’ll need a result variable, a
looping construct, type coercion, and finally logging the output. Let us try this code.
program.js
var result = 0;
console.log(result);
learnyounode verify program.js
3. My First I/O!
Moving on, we will now select the third challenge, My First I/O!
Exercise 3 provides us with the following instructions:
In this example we start interacting with the file system using NodeJS. To do so, we pull in
the fs, or file system, module into our Node environment. This gives us access to a wealth
of methods for file input and output. The node documentation provides a great overview of
how File I/O is handled.
For this we will use the following code:
program.js
var fs = require('fs');
console.log(lines);
Learn more about require(‘fs’), fs.readFileSync(), buf.toString() and
console.log().
4. My First Async I/O!
This step adds one of the main ideas of Node.js, and that is asynchronous operations. This
program needs to use just one asynchronous operation to read a file and provide the count
of newlines it has to the console. We will need to make use
of fs.readFile() and Callbacks for this. Read this snippet from the official documentation
about asynchronous forms of methods:
The asynchronous form always takes a completion callback as its last argument. The arguments
passed to the completion callback depend on the method, but the first argument is always reserved
for an exception. If the operation was completed successfully, then the first argument will be null or
undefined.
The asynchronous form is referring to the asynchronous version of any given I/O method.
This is because require(‘fs’) has both synchronous and asynchronous versions of all the
available methods.
Let’s look at the solution.
var fs = require('fs');
var file = process.argv[2];
var fs = require('fs');
var path = require('path');
list.forEach(function (file) {
console.log(file)
});
});
// solution_filter.js
var fs = require('fs');
var path = require('path');
callback(null, list)
})
}
Our module example made use
of module.exports, process.argv(), console.error(), console.log(), require(‘fs’), require(‘path’
), fs.readdir(), and path.extname().
7. Http Client
The HTTP Client example is the quintessential hello world type demonstration of what
makes NodeJs so cool. With just a minimum amount of code, you can build a fully
functional HTTP client in Node.js. The HTTP Client example makes use of the Node http
core module which you can bring into the project with a simple require(‘http’). From there
you will then have access to all of the methods it offers, one of which is http.get(). In
addition to this, we are introduced to two new concepts in NodeJs and that is
the Stream system and Event system.
var http = require('http');
data = data.toString();
console.log(data.length);
console.log(data);
}));
});
The Http Collect example made use
of require(‘http’), require(‘bl’), process.argv(), response.pipe(), buf.toString(), console.log()
and console.error()
9. Juggling Async
Juggling Async in Node is no walk in the park. This is one of the more difficult aspects to
deal with, and this exercise is designed to show you how to do it. The concept of counting
callbacks is introduced here as it is the fundamental way of managing async when working
in Node.js. Packages such as async and after make this task much easier. This example
uses the grunt worker approach.
var http = require('http');
var bl = require('bl');
var results = [];
var count = 0;
function printResults() {
for (var i = 0; i < 3; i++) {
console.log(results[i]);
}
function httpGet(index) {
http.get(process.argv[2 + index], function (response) {
response.pipe(bl(function (err, data) {
if (err) {
return console.error(err);
}
results[index] = data.toString();
count++;
if (count == 3) {
printResults();
}
}));
});
}
function zeroFill(i) {
return (i < 10 ? '0' : '') + i;
}
function now() {
var d = new Date();
return d.getFullYear() + '-'
+ zeroFill(d.getMonth() + 1) + '-'
+ zeroFill(d.getDate()) + ' '
+ zeroFill(d.getHours()) + ':'
+ zeroFill(d.getMinutes());
}
server.listen(Number(process.argv[2]));
The time server example uses require(‘net’), net.createServer(), socket.end(),
and server.listen().
11. Http File Server
This is an example of an HTTP file server. The task is to create one in Node.js that
responds with the same text file for every request it gets. Since we’re dealing with HTTP
we will of course use the http module of Node core. We’ll also use the file system module
to help us create the solution.
var http = require('http');
var fs = require('fs');
fs.createReadStream(process.argv[3]).pipe(res)
});
server.listen(Number(process.argv[2]));
req.pipe(map(function (chunk) {
return chunk.toString().toUpperCase();
})).pipe(res);
});
server.listen(Number(process.argv[2]));
Our Http Uppercaser worked and was made possible by require(‘http’), require(‘through2-
map’), http.createServer(), method.method(), response.end(), readable.pipe(), buf.toString(
), and server.listen().
13. Http Json Api Server
We have made it to the final challenge! This final challenge is to build an HTTP server that
servers Javascript Object Notation data upon receiving an HTTP GET request to the path
of ‘api/parsetime’. The request will include a query string which has a key of ‘iso’ and a
value of an ISO formatted time. This might look something like /api/parsetime?iso=2013-
08-10T12:10:15.474Z. There will also be a second endpoint clients can make requests to.
This will be for the purpose of parsing unixtime and will live at /api/unixtime. This endpoint
will be able to parse the same query string as the first, but it will respond differently. It will
respond with UNIX epoch time in milliseconds. This refers to the number of milliseconds
that have elapsed since January 1 1970 00:00:00 UTC. A challenging task for sure.
var http = require('http');
var url = require('url');
function parsetime(time) {
return {
hour: time.getHours(),
minute: time.getMinutes(),
second: time.getSeconds()
}
}
function unixtime(time) {
return {unixtime: time.getTime()}
}
if (/^\/api\/parsetime/.test(req.url))
result = parsetime(time);
else if (/^\/api\/unixtime/.test(req.url))
result = unixtime(time);
if (result) {
res.writeHead(200, {'Content-Type': 'application/json'});
res.end(JSON.stringify(result))
} else {
res.writeHead(404);
res.end();
}
});
server.listen(Number(process.argv[2]));
The Http Json Api Server made use of a myriad of methods
including require(‘http’), require(‘url’), http.createServer(), url.parse(), response.writeHead()
, server.listen(), and process.argv().
Best Way To Learn Node.js Summary
So was this the best way to learn Node.js or what?! When I found those interactive
tutorials by NodeSchool.io, I knew it was time to get our hands dirty with Node. These
interactive lessons really did cover a lot of ground. To be honest, as a new comer to Node
myself, I found the exercises to be difficult. Surely with practice and patience,
programming in Node will become easier – but it’s great that we covered as much as we
did here. Like any other programming library or framework, it comes down to learning the
methods of the classes offered, learning what arguments they expect, and what you can
do with them. Node is like taking JavaScript and putting it on steroids. There is a ton it
offers, but the learning curve can be fairly steep.
Further Reading
If you find that you just can’t get enough NodeJS learning, then you must continue to these
epic resources to further your Node foo.
• NodeSchool.io
• The Art of Node (an introduction to Node)
• Node.js guide
• The Node.js blog
You Might Still Need jQuery, and this is why. Web developers are a fickle
crowd. Yesterday’s best practices become today’s code smells, and today’s
code smells may at one point end up being best practices. Friends, we are out
of control. What is it that makes us so crazy and all over the place? Why do
development workflows come in and out of fashion at such a rapid pace? Why
does this problem seem to be getting worse and not better?! Right now, native
JavaScript is all the rage. “Death to jQuery!” the hipsters shout. It’s really not
quite that simple, let’s take a look at why this is so.
Web Developers Are Obsessive Compulsive
Once we find a new toy to play with, and get halfway decent with it, we must suddenly
rewrite the entire world in said new toy. This groupthink feeds on itself, and pretty soon not
only are you the only one that needs to rewrite everything with the new toy, now everyone
needs to rewrite the world in the new toy!
What is Cool?
Here is a challenge to you. Stop following what is cool. Stop trying to figure out the next big
thing. Stop trying to be ahead of the curve. You are making youself miserable, and killing
yourself in the process. How about looking at the particular challenge in front of you, and
figuring out a way to solve your problem. As you think about solving your challenge, if you
are worried about how others will perceive you based on your approach, you’re an idiot.
Don’t be an idiot.
A Re Introduction To jQuery
Ultimately, this leads us to a re introduction to jQuery. As a person who like to go against
the grain, I take great joy in blogging about the virtues of jQuery. When a backlash reaches
the heights it has currently for something like jQuery – then it is definitely a sign to dig your
heels in. PHP backlash is also popular. Guess what? PHP fucking rocks. Laravel takes a
lot of flack lately. Guess what? Laravel is the best PHP framework ever invented. Haters
can suck it.
jQuery is a great way for newer web developers or designers to ease their way into native
JavaScript coding. When John Resig came up with the syntax for jQuery, it was and
remains a simply genius idea. Grab something in the page by a CSS selector, then do
anything you want with it. The simple fact that this is so easy to do, and so useful, certainly
merits included jQuery in any application. Many of us, myself included, actually made
things like DOM manipulation, animations, event handling, and AJAX happen in jQuery
before we were ever able to natively. This lowers the bar for people new to the field, and
really is quite fun. Nowhere else can you get as much bang for your buck as a beginning
programmer, than to be able to make some incredible animations and effects in the
browser with just a couple lines of code. This gets newbies excited, and hungry to further
their skills.
This article take a fresh look at a Mithril JavaScript Tutorial. Recently we were
taking a look at the very slick Flarum Forum Software here at Vegibit, and one
of the things we discovered is that it makes use of a great high performance
JavaScript framework called Mithril. Peaking our interest, we decided to read up
more about Mithril and have a play with the features it offers ourselves. What
we found was an incredibly small footprint, and blazing performance, all the
while staying true to a mostly native JavaScript syntax. Mithril Js is really cool,
let’s learn all about it now.
<div id="mfunction"></div>
First we used the m() function to create a virtual anchor tag with bootstrap classes
assigned. This was assigned to the variable renderthis. Next, we grab the element on the
page with the id of one, and assign that to the variable attachto. Finally, we call
the m.render() function and pass to it the attach point, and the newly created element to
render. Cool stuff!
var Button = {
view: function () {
return m('a.btn btn-primary', 'This is also a button, but it is blue.');
}
};
m.mount(attachto, Button);
<div id="basiccomponentone"></div>
A more common way to display elements on the page is by using components. To do this
requires a few steps.
Following these steps, we create a JavaScript object named Button, store a function in
it’s view property, then pass the object to m.mount as the second argument. The first
argument is where we want to attach it in the DOM.
Let’s look at another way to create a component, with a Hello World type example. This
time around, we will say “Hello Mithril” using Mithril of course.
attachto = document.getElementById('basiccomponenttwo');
app.view = function () {
return m('h3', 'Hello Mithril!');
};
m.mount(attachto, app);
<div id="basiccomponenttwo"></div>
var State = {
count: 0,
controller: function () {
this.count++;
},
view: function (controller) {
return m('button.btn btn-success', {onclick: this.controller.bind(this)}, "The button has
been pressed " + this.count + " times!");
}
};
m.mount(attachto, State);
<div id="applicationstate"></div>
In this example, we start to look at the ability to change state in JavaScript, and have our
views be updated in real time. If you click the button, you will see that each time you click
it, the count increments. How does this happen? The key is writing views that reflect the
state of your application.
The function contained in view will be run anytime an event which has been created in that
function gets fired. It works kind of like this:
<div id="twowaydatabinding"></div>
Did you try typing some text into the text box? Cool, right?! How does it work?
Well, the official documentation tells us that in Mithril, a component is simply an object
which has both a controller and view function. So it looks like we meet the requirements of
having a component since we have an app object, which holds a function in both
it’s controller and view properties. As you type in the text field, a property
called stuffwetype gets updated. This is due to the getter / setter functionality of m.prop().
The changes that occur to this property trigger visual updates in the View. Now comes the
funky part, m.withAttr(). m.withAttr() is a little tricky to grasp at first, but we’ll step through
it here. First off, the official Mithril documentation tells us the following:
The m.withAttr utility is a functional programming tool provided by Mithril to minimize the need for
anonymous functions in the view.
m.withAttr() takes two arguments.
The first is a string representation of the element in the DOM to fetch. Note
that m.withAttr() occurs inside of the call to m() which renders an input element. We are
passing the string value of value to m.withAttr(). In this context, we are saying we want
the current DOM value of the value property of the input element. Now, here is the tricky
part.
The second argument passed to the m.withAttr() function is itself a callback. In other
words, it is a function that will run, and here is the kicker: It is passed the property value of
said element into it upon execution. In our case, we can see that the callback (argument
two of m.withAttr()) is input.stuffwetype. As it turns out, what is stored
in input.stuffwetype is the m.prop() getter / setter function which we declared in the
controller. So this is what we mean by m.prop() and m.withAttr()working together. In an
indirect kind of way, m.prop() is usually the second argument passed to m.withAttr().
Don’t you just love functional programming?!
withAttr Example
We’ll look at another example just to be sure we see how this special function works.
var withAttrComponent = {
showoutput: function (withAttrResult) {
m.render(document.getElementById('withAttr'),
m('div.alert alert-success', ['The button you clicked has the class of ',
m('b', withAttrResult)]));
},
view: function () {
return m(
'button.btn-lg',
{onclick: m.withAttr('class', this.showoutput)},
'What class do I have?'
);
}
};
m.mount(document.getElementById('buttonlarge'), withAttrComponent);
In this example, the second argument to m.withAttr() is this.showoutput just for fun. We
know that the button on the page has a class of btn-lg, since this is how we constructed
our view. Now, we can almost read the code of the call to m() in that view function like so:
Go get me the value of the class property of the button element in the page, then call the
function that exists in this.showoutput, and pass the value you found in step one to that
function.
We create a simple little function that then renders the result of that operation onto the
screen. If all went well, you should see “The button you clicked has the class of btn-lg”
when you actually clicked the button. Smashing!
// We now employ a JavaScript constructor to set up two properties, taskdescription and isfinished
task.Todo = function (data) {
this.taskdescription = m.prop(data.taskdescription);
this.isfinished = m.prop('false');
};
//adds a task to the list, and clears the description field for user convenience
_vm.add = function () {
if (_vm.taskdescription()) {
_vm.list.push(new task.Todo({taskdescription: _vm.taskdescription()}));
_vm.taskdescription('');
}
};
};
return _vm
}());
// the controller defines what part of the model is relevant for the current page
// in this case, there's only one viewmodel that handles everything
task.controller = function () {
task.viewmodel.init()
};
};
<body>
</body>
</html>
Object Literals
It is very easy to create an object literal in JavaScript. Let’s a few examples.
You can command an object into existence with a line of code just like this.
var firstobject = {};
Instead of creating an empty object, you could define an object and populate some values
in one shot.
var firstobject = {
color: 'blue',
holiday: 'Christmas',
day: 25
};
Cool stuff. Now, the left side of each key / value pair is referred to as the property. Each
property should have some corresponding value, and multiple properties are separated by
commas. You can also nest Objects very easily like so.
var game = {
name: 'Minecraft',
price: 29.99,
arrival: {
day: 'Thursday',
date: 'December 17th, 2015',
devloper: 'Mojang'
},
info: {
platform: 'Wii U',
company: 'Nintendo'
}
};
If you try to access a value on a non existent property, you will be returned undefined.
game.difficulty
// undefined
You can however check for an undefined value and fill in a default value if you like using
the ||operator.
var difficulty = game.difficulty || 'easy!';
// easy!
Functions
Functions are where the magic happens. According to Crockford, Functions are the best
thing about the JavaScript language. Functions are linked to Function.prototype.
• Method Invocation
• Function Invocation
• Constructor Invocation
• Apply Invocation
Method Invocation
If a function is stored within the property of an object, then it can be thought of as
a method. Here comes the confusion: The this keyword. The
JavaScript this implementation is the most confusing and convoluted thing seen among
any language that implements some form of this. When a method is invoked, the value
of this is bound to that specific object. How do you know if you are calling a method? If
you are using a refinement such as the . operator, then you are calling a method. Let’s
see an example.
crockford = {};
crockford.fact = 'On the first day, Crockford created JSON and it was good, on the second day he
rested.';
crockford.preach = function () {
var message = this.fact;
$('#clickmethodinvocation').click(function () {
$('#methodinvocation').html(message);
});
};
// method invocation
crockford.preach();
<div id=”methodinvocation”>
On the first day, Crockford created JSON and it was good, on the second day he rested. (
In this context, this points to the crockford object )
Function Invocation
If a function is not a property on an object, then when it is invoked, it is done so as a
function. A function that is invoked as a function has this bound to the global object,
typically the Window object. Let’s verify this claim.
function randomfact() {
var message = 'Everytime you create a global variable, Douglas Crockford roadhouse kicks an
intern';
if (this == '[object Window]') {
message += ' ( this is equal to <b>[object Window]</b> )';
$('#functioninvocation').html(message);
}
}
// function invocation
randomfact()
Constructor Invocation
There are no classes in JavaScript, but you can create new object instances in a similar
way to calling a construct method in more traditional object oriented programming
languages. Oddly enough, getify makes a good point in that what is commonly referred to
as object oriented programming languages should actually be referred to as class based
programming languages. At this point, the terminology is too entrenched but if you think
about it, it makes sense. In the classical OOP style, you create instances of objects that
are based on classes! JavaScript does not work like this at all. In JavaScript objects are
derived from other objects. Let’s see how.
var House = function (windows, color) {
this.windows = windows;
this.color = color;
};
House.prototype.getwindows = function () {
return this.windows;
};
House.prototype.getcolor = function () {
return this.color;
};
$('#clickconstructorinvocation').click(function () {
$('#constructorinvocation').html('House two has ' + house2.getwindows() + ' Windows and is ' +
house2.getcolor() + ' in color.');
});
Apply Invocation
One mind bender about JavaScript is that functions can have methods. One of those
methods is the apply method. What it does, is to allow us to provide an array of arguments
to pass to the function, in addition to allowing us to specify which object should be
referenced by this. The first parameter to the apply method is what this should be bound
to. The second argument is the array of arguments to pass to the function. Let’s see it in
action.
var car = {
make: 'Subaru',
model: 'WRX'
};
var truck = {
make: 'Nissan',
model: 'Titan'
};
function describe(info) {
return info + ' ' + this.make + ' ' + this.model;
}
$('#clickapplyinvocation').click(function () {
$('#applyinvocation').html(describe.apply(truck, [2015]) + ' ( <code>this</code> bound to
<code>truck</code> )<br> ' + describe.apply(car, [2016]) + ' ( <code>this</code> bound to
<code>car</code>) ');
});
Arguments
When functions are called, the have access to a hidden arguments parameter. What it
does is to count the number of parameters that were passed into the function, and
provides access to those values. This is why you can write a function and not have to
specify how many parameters it needs.
var sum = function () {
var i, sum = 0;
for (i = 0; i < arguments.length; i += 1) {
sum += arguments[i];
}
return sum;
};
$('#clickarguments').click(function () {
$('#arguments').html(sum(1,2,3,4,5,6,7,8,9));
});
Click To See Arguments in Action! Clear
<div id=”arguments”>
45
Exceptions
Douglas Crockford doesn't need to use try-catch. When Douglas Crockford writes code,
there are no exceptions. It turns out however, that JavaScript does provide an efficient
means of handling exceptions. You are not Douglas Crockford, and as such may
encounter errors. Learn how to deal with these exceptions with this example.
var adder = function (one, two) {
if (typeof one !== 'number' || typeof two !== 'number') {
throw {
name: 'TypeError',
message: '<code>adder()</code> needs numbers'
}
}
return one + two;
};
$('#clickexceptions').click(function () {
tryadding();
});
Recursion
Recursion can almost be thought of as a form of looping. A function can call itself to break
up a problem into smaller subproblems. When all of the subproblems are complete, the
recursion has run it's course. JavaScript does not have tail recursion optimization. What
that means is that if you screw up the logic in your recursive function, you very well could
crash the programming environment by exhausting the return stack. Here is an example of
the Towers of Hanoi puzzle solved with recursion.
var recurred = '';
var hanoi = function (disc, source, temporary, destination) {
if (disc > 0) {
hanoi(disc - 1, source, destination, temporary);
recurred += 'Move disc ' + disc + ' from ' + source + ' to ' + destination + '<br>';
hanoi(disc - 1, temporary, source, destination);
}
};
$('#clickrecursion').click(function () {
hanoi(4, 'Soure', 'Temporary', 'Destination');
$('#recursion').html(recurred);
});
JavaScript Scope
Scope in JavaScript is a beast, especially if you are used to scoping rules from other
languages. So just what is Scope? Well, it's where to look for things. It's not really much
more complicated than that. In JavaScript, we have function scope. Let's take a look at an
example.
var fact = 'Doug Crockford can go back in time like superman, as he did with ES4 to make ES5.';
function roundhouse() {
var fact = 'Douglas Crockford doesnt sleep, he waits to be triggered.';
function jslint(fact) {
fact = 'If you execute "typeof Crockford" your browser will return "awesome"';
amazing = 'At the end of every prototype chain is Doug Crockford.';
}
jslint();
}
roundhouse();
fact; // Doug Crockford can go back in time like superman, as he did with ES4 to make ES5.
amazing; // At the end of every prototype chain is Doug Crockford.
jslint(); // ReferenceError: jslint is not defined
• 1. Hey global scope, I have a declaration for a variable called fact. The global scope
says, "I got it, you can move on now".
• 2. Hey global scope I have a function called roundhouse(), and I want to register him
in the global scope. Global scope meets this request and roundhouse() is now
registered in the global scope.
• 3. We now descend into the roundhouse function and we say, hey roundhouse
scope, I have a declaration for the variable called fact. Function scope roundhouse
now has this variable declared.
• 4. We are still in the scope of roundhouse(), and we now come across
a jslint() function. So what happens? Hey roundhouse() scope, I have a function
declaration for function jslint(). Scope of roundhouse() replies back and says great,
I've got him registered.
• 5. We now descend into the jslint() scope. Hey scope of jslint(), I've got an implicit
variable declaration for fact. Scope of jslint() responds back and says ok, you've got
your fact variable declared.
• 1. Hey global scope, I have an LHS (Left Hand Reference) for a variable called fact,
ever heard of him? Global scope responds, "Yep I sure have, here is the reference to
that variable". At that point the value of 'Doug Crockford can go back in time like
superman, as he did with ES4 to make ES5.' is immediately assigned to
the fact variable in the global scope.
• 2. At this point during the execution phase, we jump right down to the call
to roundhouse(). The lines above that were taken care of during the compilation
phase.
• 3. Hey global scope I have an RHS (Right Hand Reference) for a variable called
roundhouse, have you heard of him? Global scope responds, "sure, I got him, here
you go - here is a reference to that variable." Now, we can retrieve that value and we
find that it is a function object. We also see that roundhouse is immediately followed
by the innvocation operator so we execute that function.
• 4. Hey scope of roundhouse(), I have an LHS reference for a variable called fact,
have you heard of him? The roundhouse scope responds back, "I sure have heard of
him, here is the reference to that variable." Now do note, this is the fact variable that
lives in the roundhouse scope, *not the global scope*! With that, the value of
'Douglas Crockford doesnt sleep, he waits to be triggered.' is assigned to
the fact variable in roundhouse scope.
• 5. At this point we skip down to the call to jslint() and it goes a little something like
this. "Hey scope of roundhouse(), I have an RHS reference for a variable
called jslint, have you heard of him? The roundhouse() scope responds back, "Yep,
here is the reference to that variable." We then find his value, and find it is a function
object and then immediately execute it.
• 6. We then move into the scope of jslint() and the conversation goes like this. Hey
scope of jslint() I have an LHS reference for a variable named fact, have you heard
of him? The scope of jslint() responds back and says, "Yes indeed, here is the
reference to that variable." This is true because fact was declared as a named
parameter. At this point the string 'If you execute "typeof Crockford" your browser will
return "awesome"' gets assigned to fact in the scope of jslint().
• 7. Now we move to the next line and we say, hey scope of jslint, I have an LHS
reference for a variable named amazing, ever heard of him? The scope of jslint will
respond with, "I've never heard of this variable amazing you speak of, go fish." What
this means is since this scope does not have what you are looking for, go look in the
next scope. So that is just what we do. Hey scope of roundhouse(), I have an LHS
reference for a variable named amazing, ever heard of him? The scope of
roundhouse will now respond with, "I've never heard of this variable amazing you
speak of, go fish." Ok, let's keep going. We are now in the global scope. Hey global
scope I have an LHS reference for a variable named amazing, ever heard of him?
The global scope will now respond with, "I've never heard of this variable amazing you
speak of but since I like you, I will create one for you as if by magic, here is your
reference to that variable". Just like that, you have created a new variable in the
global scope, that you may have not intended to.
$('#clickscope').click(function () {
$('#scope').html(amazingfacts);
});
<div id="scope">
Doug Crockford can go back in time like superman, as he did with ES4 to make ES5.
At the end of every prototype chain is Doug Crockford.
Closure
Closure depends on Lexical Scope. In order to actually understand closure, you must first
understand lexical scope. Lexical scope is the understanding of declaring variables within
their given scope, and is set in stone upon compilation. Lexical scope states that variables
that belong to this function scope, do not belong to that function scope. The author of the
software makes the decision ahead of time which variables will belong to which scope.
So what it Closure? The definition by getify is the one that sums it up best.
Closure is when a function remembers its lexical scope even when the function is executed outside
that lexical scope.
I know we dedicated this article to Crockford, but Getify just might be the next Crockford -
so we gotta get with the times. Let's look at some example code.
function crockford() {
var fact = "Douglas Crockford variable scopes are his fists";
function nunchucks() {
console.log(fact);
}
swing(nunchucks);
}
function swing(nunchucks) {
nunchucks(); // "Douglas Crockford variable scopes are his fists"
}
crockford();
Here we have an outer function named crockford(), and he has a variable named fact in
his scope.
There is an inner function named nunchucks() which has it's own scope bubble, which
lives inside the scope bubble of crockford(), it is a nested scope.
We then take a reference to the function nunchucks() and pass it as a parameter to
a swing() function which lives outside of the scope bubble of
both nunchucks() and crockford().
When the nunchucks() function on line 12 executes outside of the scope where it was
defined, it still has access to the variables contained in the lexical scope where it was
originally defined. This is in fact closure.
fade(document.getElementById('closure2ex'));
});
Let's see how this code is an example of Closure. We begin by calling the fade() function
and pass in a dom element. fade() sets it's level to one and defines a step()
function. fade() then calls the setTimeout() function with the step() function as the first
parameter, and 100 milliseconds as the second. The fade() function returns, and it has
finished executing. fade() is now done.
100 milliseconds later, step() gets invoked again. In order to do it's work, it needs to have
access to the level variable which belongs to the fade() scope. Remember, fade() has
already executed and returned, it is a memory at this point. It's variable level however
lives on, as long as the inner function step() needs it to do it's job. Check out this
Crockford Good Part Example:
Callbacks
Callbacks are also known as higher order functions. This is to say that a callback, is a
function which is passed to another function as a parameter, and that passed function is
then called or executed inside the function it was passed to, usually after a condition is
met, or after a set period of time. It is very popular in JavaScript, so much so that we refer
to it as the callback pattern.
Let's see an example where we set up two functions. First we create
a callbackfunction() which outputs some text to the screen when it is executed. Then we
create a firstfunction() which we pass two parameters. The first parameter is some text
as a message which firstfunction() will use to output to the browser. We also
pass callbackfunction as the second argument to firstfunction(). Finally, we attach a
click event to a button to execute the firstfunction() when clicked. Check out the results.
function callbackfunction() {
$('#callbackex').append('<span class="text-primary">However I come from
<code>callbackfunction()</code>!</span>');
}
$('#clickcallback').click(function () {
firstfunction('<span class="text-danger">I come from <code>firstfunction()</code>!</span><br>',
callbackfunction);
});
function last() {
$('#callbackex2').append('<b>This is Last! 1 Second Callback Delay</b><br>');
}
}
$('#clickcallback2').click(function () {
callback2();
});
Click To See callback in Action! Clear
<div id="callback2">
This is First
This is in the Middle!
This is Last! 1 Second Callback Delay
Modules
The classic module pattern is one of the most used patterns in all of JavaScript. It has a
couple of characteristics that actually make it a module. The first characteristic is that the
module must have an outer wrapping function which gets executed. The second
characteristic is that there has to be a least one inner function that gets returned out and
keeps a closure over the internal state. The purpose of the module pattern is to provide a
mechanism to emulate traditional class based programming concepts by offering the ability
to include public and private methods and variables inside a single object, which allows
you to determine what information you would like to expose to consumers of the module.
This pattern makes use of closures to provide this idea of privacy and state. You should
only return the public API of the module, leaving all other methods and variables private
inside the module. We can see how this might be confusing! Before you can understand
Modules, you need to understand Closures. Before you understand Closure, you need to
have Lexical Scoping down cold. So if it doesn't click right away, go back and review
Lexical Scoping, then Closure, then revisit Modules. Let's see an example.
var module = (function factory() {
var privateobject = {fact: "Douglas Crockford can have full conversations using only javascript's
reserved words."};
return {
preach: function () {
console.log(privateobject.fact);
}
};
})();
module.preach();
Person.prototype.myname = function () {
return 'I am ' + this.name;
};
Person1.greet = function () {
$('#delegationex').html('Hello, my name is ' + this.myname() + '!<br>');
};
Person2.greet = function () {
$('#delegationex').append('Hi, my name is ' + this.myname() + '!');
};
Person1.greet();
Person2.greet();
Arrays
Douglas Crockford refers to Arrays in JavaScript as an object that has array-like features,
as if to say it is not really an array. The reason for this is because JavaScript converts the
array subscripts into strings, and those strings become properties on the object. Getting
and Setting values to and from arrays works just like getting and setting values in objects.
Let's see how to create an Array Literal here.
var myarray = [
'Lucky Number 7', function () {
}, anobject = {make: 'Porche', model: '911 Turbo'}, 767, true,
false, [], null, undefined, NaN
];
console.log(myarray.length);
console.log(typeof myarray[0]);
console.log(typeof myarray[1]);
console.log(typeof myarray[2]);
console.log(typeof myarray[3]);
console.log(typeof myarray[4]);
console.log(typeof myarray[5]);
console.log(typeof myarray[6]);
console.log(typeof myarray[7]);
console.log(typeof myarray[8]);
console.log(typeof myarray[9]);
Click To See arrays in Action! Clear
<div id="arrayex">
myarray[0] holds a string
myarray[1] holds a function
myarray[2] holds a string
myarray[3] holds a object
myarray[4] holds a number
myarray[5] holds a boolean
myarray[6] holds a boolean
myarray[7] holds a object
myarray[8] holds a object
myarray[9] holds a undefined
As you can see we can assign any type we like to an array slot. In our example we place a
string, function, object, number, a couple of booleans, an array, null, undefined and NaN
into our array. In one of the quirky effects of JavaScript, if you apply a typeof operator to all
of these, you can see that almost everything is an object, save for NaN which is actually
undefined. JavaScript!
The length property is quite handy in JavaScript and is often used in loops. Let's see how.
var loopingarray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
JavaScript Methods
JavaScript has a small collection of methods built into the language that will make your
development easier. In a language like PHP, you have literally thousands upon thousands
of functions built into the language. In a sense, PHP is it's own framework. JavaScript has
no such massive collection of built in functions. Perhaps this is why there are more
JavaScript frameworks than you could ever imagine. People are trying to build into the
language all of the richness of features that are required for web development. In any
event, it will do you much good to be familiar with the built in methods of the language.
Here are the links to the ones you want to know.
• Array Methods
• Function Methods
• Number Methods
• Object Methods
• RegExp Methods
• String Methods
2. Array.prototype.push()
array.push(element1, …, elementN)
Overview
The push() function appends the arguments given to it, in order, to the end of the array. It
modifies the array directly, rather than creating a new array.
What push() returns
When you make a call to push(), it returns the total number of items in the array, after any
provided arguments have been added to the end of the array.
array.push() function examples
var characters = ['Darth Vader', 'Yoda', 'Boba Fett'];
var total = characters.push('Luke Skywalker', 'Han Solo');
console.log(characters); // ["Darth Vader", "Yoda", "Boba Fett", "Luke Skywalker", "Han Solo"]
console.log(total); // 5
3. Array.prototype.indexOf()
array.indexOf(searchElement[, fromIndex = 0])
Overview
The JavaScript indexOf() function searches an array for an element that contains a
specific value, then returns the very first index that contains that value. You can provide a
starting index to the function if you like, otherwise searching will begin from index 0.
What indexOf() returns
The lowest index that is greater than or equal to the start of the array at which the element
is equal to the given value. If no match is found, the indexOf() function returns -1.
array.indexOf() function examples
var starwars = ['Episode 4: A New Hope',
'Episode 5: The Empire Strikes Back',
'Episode 6: Return of the Jedi',
'Episode 1: The Phantom Menace',
'Episode 2: Attack of the Clones',
'Episode 3: Revenge of the Sith',
'Episode 7: The Force Awakens'];
The example above is a little more tricky. We have an array of enemies, and there might
be multiple of a given enemy. By making use of indexOf(), we can find all instances of
‘Storm Trooper’ in our array of enemies. Running the code shows us that we have found a
Storm Trooper at index 2 and index 5 of our array.
function theGoodSide(goodguys, goodguy) {
if (goodguys.indexOf(goodguy) === -1) {
goodguys.push(goodguy);
console.log('The new goodguys are ' + goodguys);
} else if (goodguys.indexOf(goodguy) > -1) {
console.log(goodguy + ' is already part of the goodguys.');
}
}
This example makes use of a custom function that we can use to make sure our good
guys are all accounted for. We check to see if the character exists in our collection, and if
not, we add them to our good side.
4. Array.prototype.slice()
array.slice([begin[, end]])
Overview
The JavaScript slice() function takes a start and end argument. It uses these start and
end points to reach into the array, and remove a specific number of elements. The position
you reference by start is included in the results, but the end is not included. In other words
all elements are returned from the start right up to, but not including the end element. If
you do not provide an end value, slice() will return the rest of the array starting from the
given starting point. The original array is left in tact.
What slice() returns
The slice() function returns a new array that contains all of the elements of the original
array from the element specified by the starting point provided, and up to but not including,
the element specified by the ending point provided.
array.slice() function examples
var vaderparts = ['helmet', 'left arm', 'right arm', 'left leg', 'right leg'];
var chopped = vaderparts.slice(2,3);
console.log(chopped); // right arm
5. Array.prototype.toString()
array.toString()
The toString() function converts all elements in an array to strings and outputs one big
string as a comma separated list of items.
array.toString() function examples
var spacecraft = ['X Wing', 'Death Star', 'Millenium Falcon', 'Jedi Interceptor'];
var allspacecraft = spacecraft.toString();
console.log(allspacecraft);
// X Wing,Death Star,Millenium Falcon,Jedi Interceptor
6. Array.prototype.filter()
array.filter(callback[, thisArg])
Overview
The JavaScript filter() function is very useful for doing exactly what it says, filtering
down a collection of elements based on a given test. When you call the filter() function,
you need to pass it a callback. This callback is executed against every element in the
array. If that callback results in a true value, that particular element is added to a new
array. The original array is left unchanged.
What filter() returns
filter() returns a new array that contains only the elements of the original array that
returned true when the provided callback ran.
array.filter() function examples
var summer = [10, 20, 30, 40, 50, 60, 70, 80].filter(function niceweather(temperature) {
return temperature >= 70;
});
console.log(summer); // 70, 80
var spacecraft = [
{name: 'Tie Fighter', speed: 200000},
{name: 'Super Star Destroyer', speed: 300000},
{name: 'Death Star', speed: 400000},
{name: 'T65 X Wing Star fighter', speed: 500000},
{name: 'T47 Air (snow) Speeder', speed: 600000},
{name: '74-Z Speeder Bike', speed: 700000},
{name: 'Millenium Falcon', speed: 800000}
];
function filterBySpeed(spacecraft) {
return spacecraft.speed > 450000;
}
fleet.forEach(function (craft) {
console.log(craft.name);
});
7. Array.prototype.join()
string = array.join([separator = ‘,’])
Overview
The join() function converts each element of an array to a string and then concatenates
those strings together. If the separator string was provided, it gets inserted between all
elements in the final string.
What join() returns
The string that results from converting each element of the original array to a string and
then joining them together, with the separator string between elements.
array.join() function examples
var wisdom = ['Yoda Says', 'Fear is the path to the dark side. Fear leads to anger. Anger leads to
hate. Hate leads to suffering.'];
wisdom = wisdom.join(': ');
console.log(wisdom);
// Yoda Says: Fear is the path to the dark side. Fear leads to anger. Anger leads to hate. Hate
leads to suffering.
var wisdom = ['Do. Or do not. There is no try', 'Luminous beings are we…not this crude matter', 'Wars
not make one great', 'Judge me by my size, do you?', 'Truly wonderful, the mind of a child is'];
var wisdom = wisdom.join(' <=***=> ');
console.log(wisdom);
// Do. Or do not. There is no try <=***=> Luminous beings are we…not this crude matter <=***=> Wars
not make one great <=***=> Judge me by my size, do you? <=***=> Truly wonderful, the mind of a child
is
8. Array.prototype.splice()
array.splice(start, deleteCount[, item1[, item2[, …]]])
Overview
The splice() function deletes zero or more elements beginning from the provided start
location, and replaces those elements with zero or more new values that were provided.
Existing items in the array are shifted as needed to make room for any added or deleted
elements. The thing to remember about the splice() function, is that it does modify the
original array directly.
Returns
An array which contains any elements that may have been deleted from the array.
array.splice() function examples
var darkSide = ['Darth Vader', 'Grand Moff Tarkin', 'Boba Fett', 'Emperor Palpatine'];
//-----------------------------------------------------//
//-----------------------------------------------------//
//-----------------------------------------------------//
//-----------------------------------------------------//
// removes 2 elements from index 0, and inserts 'Count Dooku', 'General Grievous' and 'Asajj
Ventress'
removed = darkSide.splice(0, 2, 'Count Dooku', 'General Grievous', 'Asajj Ventress');
console.log(darkSide);
// ['Count Dooku', 'General Grievous', 'Asajj Ventress', 'Darth Maul', 'Emperor Palpatine']
console.log(removed);
// ['Darth Vader', 'Grand Moff Tarkin']
//-----------------------------------------------------//
9. Array.prototype.forEach()
array.forEach(callback[, thisArg])
Overview
The forEach() function executes a provided function on each element of the
array. forEach() has no return value and does not return the original array. forEach() is
related to the map(), filter(), every(), and some() functions and as such they share some
related details. They all expect a callback function as the first argument. The optional
second argument is a way to specify the this value for the callback function. All of these
functions check the length of the array before looping. If the provided callback adds
elements to the array during it’s execution, those elements are not included for looping by
the forEach(). Also of interesting note is that if the callback changes values in the original
array before they are looped over, those changed values will be passed during their
callback execution.
array.forEach() function examples
var planetsAndMoons = ['Alderaan', 'Bespin', 'Coruscant', 'DQar', 'Dagobah', 'Endor', 'Geonosis',
'Hosnian Prime', 'Hoth', 'Jakku', 'Kamino', 'Kashyyyk', 'Lothal', 'Mustafar', 'Naboo', 'Sullust',
'Takodana', 'Tatooine', 'Utapau', 'Yavin', 'Yavin 4'];
planetsAndMoons.forEach(listPlanets);
// planetsAndMoons[0] = Alderaan
// planetsAndMoons[1] = Bespin
// planetsAndMoons[2] = Coruscant
// planetsAndMoons[3] = DQar
// planetsAndMoons[4] = Dagobah
// planetsAndMoons[5] = Endor
// planetsAndMoons[6] = Geonosis
// planetsAndMoons[7] = Hosnian Prime
// planetsAndMoons[8] = Hoth
// planetsAndMoons[9] = Jakku
// planetsAndMoons[10] = Kamino
// planetsAndMoons[11] = Kashyyyk
// planetsAndMoons[12] = Lothal
// planetsAndMoons[13] = Mustafar
// planetsAndMoons[14] = Naboo
// planetsAndMoons[15] = Sullust
// planetsAndMoons[16] = Takodana
// planetsAndMoons[17] = Tatooine
// planetsAndMoons[18] = Utapau
// planetsAndMoons[19] = Yavin
// planetsAndMoons[20] = Yavin 4
numbers.original = [];
numbers.original.forEach(listNumbers);
numbers.forEach(listNumbers);
10. Array.prototype.concat()
var new_array = old_array.concat(value1[, value2[, …[, valueN]]])
Overview
concat() is a function that creates a new array which is the result of adding the supplied
arguments to the original array. The original array is left intact, and the new array is the
original plus any added elements. If any of the arguments to the concat() function are
themselves an array, then the elements of that supplied array are added, rather than the
entire array itself.
Returns
A new array, which is created by adding each of the supplied arguments to the original
array.
array.concat() function examples
var legoStarWarsGames = ['Empire Vs Rebels', 'Ultimate Rebel', 'The Quest for R2-D2'];
var legoStarWarsSets = [10188, 75111, 75110, 75109];
console.log(gamesAndSets);
// ["Empire Vs Rebels", "Ultimate Rebel", "The Quest for R2-D2", 10188, 75111, 75110, 75109]
var legoStarWarsGames = ['Empire Vs Rebels', 'Ultimate Rebel', 'The Quest for R2-D2'];
var legoStarWarsSets = [10188, 75111, 75110, 75109];
var availablePlatforms = ['Wii', 'Xbox', 'Playstation'];
console.log(gamesSetsPlatforms);
// ["Empire Vs Rebels", "Ultimate Rebel", "The Quest for R2-D2", 10188, 75111, 75110, 75109, "Wii",
"Xbox", "Playstation"]
11. Array.prototype.shift()
array.shift()
Overview
The shift() function removes and returns the first element of the original array. All
remaining elements in the array get shifted one slot to the left in order to fill the hole
created by removing the first element. If you try to apply this function to an empty array, it
will do nothing and simply return undefined. The shift() function does not create a new
array, it modifies the original array directly.
Returns
shift() returns the first element from the original array.
array.shift() function examples
var starWarsCreatures = ['Tach', 'Kath hound', 'Ruggers', 'Spice spider'];
12. Array.prototype.unshift()
array.unshift([element1[, …[, elementN]]])
Overview
A direct opposite to the shift() function which we just discussed, is
the unshift() function.unshift() inserts any arguments you pass to it into the beginning of
the array. All of the existing elements need to shift to the right in order to make room for
the new elements. Each argument passed to unshift() gets added in order starting from
index 0. In addition, unshift() is modifying the original array directly.
Returns
The new length of the array.
array.unshift() function examples
var starWarsCreatures = ['Eopie', 'Acklay', 'Talortai', 'Boma'];
13. Array.prototype.map()
array.map(callback[, thisArg])
Overview
This is a very useful JavaScript function, and made use of all the time in professional
software. The map() function loops over every element in the array, executing a callback
function on each item. Once map() has completed looping through the array, it takes the
results from each callback applied to each element, and returns those results in their
entirety as an array. You are left with a new array with updated values, and an old array
which has the original values. These two arrays are equal in length. When the callback is
invoked, it is done so with three arguments. Those are the value of the element, the index
of the element, and the Array object being traversed. If the optional second parameter is
provided to map(), it will be used as the this value for each execution of the callback.
note:The map() and forEach() functions seem like they are the same, but they are in fact
different. The difference is that forEach() iterates over an array and applies some
operation with side effects to each array member such as saving each one to the
database, or some other side effect. map() on the other hand iterates over an array,
updates each member of that array, and returns another array of the same size with the
transformed members (such as converting an array of strings to all lowercase).
Returns
map() returns a new array with elements computed by the provided callback function.
array.map() function examples
var starwars = ['star wars', 'the phantom menace', 'the force awakens'];
var swModified = starwars.map(function (element) {
return element.toUpperCase();
});
console.log(swModified);
// ["STAR WARS", "THE PHANTOM MENACE", "THE FORCE AWAKENS"]
console.log(one); // [3, 5, 7]
console.log(two); // [9, 25, 49]
14. Array.prototype.sort()
array.sort([compareFunction])
Overview
If you want to sort an array in JavaScript, then you can do so with the built
in sort() function. sort()applies the sort directly to the original array, no copy of the array
is made. You can optionally provide a callback function that will determine the behavior of
the sort. If you do not provide one, the sort()function will first convert all elements to
strings, and then sort based on something called the Unicode code point value. Basically
that means alphabetical, but with some special rules such as capital letters coming before
lowercase.
Returns
sort() returns a reference to the original array.
array.sort() function examples
var creatures = ['Pug jumper', 'Rong boars', 'Wamba', 'Oslet'];
creatures.sort(); //
var nums = [1, 10, 2, 21, 33, 04, 12, 09, 300];
nums.sort(); // [1, 10, 2, 21]
// Watch out that 10 comes before 2,
// because '10' comes before '2' in Unicode code point order.
var spacecraft = ['Lambda Class Shuttle', 'imperial landing craft', '4 Tantive'];
spacecraft.sort();
// In Unicode, numbers come before upper case letters,
// which come before lower case letters.
console.log(creatures);
// ["Oslet", "Pug jumper", "Rong boars", "Wamba"]
console.log(nums);
// [1, 10, 12, 2, 21, 300, 33, 4, 9]
console.log(spacecraft);
// ["4 Tantive", "Lambda Class Shuttle", "imperial landing craft"]
As we can see from the above example, when you do not supply a callback function to the
sort method, ordering may not be what you expect. The rules for ordering in Unicode are a
bit unique. For example, numbers come before upper case letters and uppercase letters
come before lowercase letters. In addition, an array of numbers is converted to strings
before sorting, so this is why we see 33 coming before 4 and 9 in the example above. Here
is a callback function example to show ordering numbers how you might expect.
var nums = [1, 10, 2, 21, 33, 04, 12, 09, 300];
nums.sort(numsasexpected);
console.log(nums);
// [1, 2, 4, 9, 10, 12, 21, 33, 300]
15. Array.prototype.pop()
array.pop()
Overview
The opposite of the push() function would be the pop() function. The pop() function
removes the last element from an array, decrements the length of the array, and returns
the value which was removed from the array. If you try to apply the pop() to an empty
array, you will simply get undefined returned.
Returns
pop() returns the last element of the array it is called on.
array.pop() function examples
var usefulFunctions = ['push', 'indexOf', 'slice', 'toString', 'filter', 'join'];
16. Array.prototype.reduce()
array.reduce(callback[, initialValue])
Overview
reduce() accepts a function as the first parameter which acts like a binary operator. This
callback function takes two values, operates on them, and returns a result. The number of
times the callback function runs is always one less than the total length of the original
array. For example if the original array has a length of 10, the callback will run 9 times. The
final result is one combined value.
Returns
The reduced value of the array, which is the return value of the last time the callback
function is executed.
array.reduce() function examples
In this example, we will use array.reduce() to operate on values contained within a simple
array of objects. array.reduce() is a little more challenging than some of the other useful
array functions, so spend some extra time on this one if it doesn’t click immediately.
var skills = [
{
name: 'Tom',
skill: 'CSS',
yearsExperience: 3,
category: 'Web Design'
},
{
name: 'Jim',
skill: 'HTML',
yearsExperience: 10,
category: 'Web Design'
},
{
name: 'Sue',
skill: 'JavaScript',
yearsExperience: 5,
category: 'Web Development'
},
{
name: 'Maria',
skill: 'PHP',
yearsExperience: 7,
category: 'Web Development'
},
{
name: 'John',
skill: 'Photoshop',
yearsExperience: 1,
category: 'Web Design'
},
{
name: 'David',
skill: 'Writing',
yearsExperience: 12,
category: 'Content'
},
{
name: 'Ellen',
skill: 'Editor',
yearsExperience: 5,
category: 'Content'
}
];
var totalexperience = skills.reduce(function (prev, current) {
return prev + current.yearsExperience;
}, 0);
console.log('The team has a cumulative experience of: ' + totalexperience + ' years!');
// The team has a cumulative experience of: 43 years!
console.log('Our workers have ' + categoryExperienceTotals['Web Design'] + ' years of Web Design
Experience, '
+ categoryExperienceTotals['Web Development'] + ' years of Web Development Experience, and '
+ categoryExperienceTotals['Content'] + ' years of Content production Experience!'
);
// Our workers have 14 years of Web Design Experience, 12 years of Web Development Experience,
// and 17 years of Content production Experience!
console.log('We have ' + workersByCategory['Web Design'] + ' employees in Web Design, '
+ workersByCategory['Web Development'] + ' in Web Development, and '
+ workersByCategory['Content'] + ' working in Content production!'
);
// We have 3 employees in Web Design, 2 in Web Development, and 2 working in Content production!
17. Array.prototype.some()
array.some(callback[, thisArg])
Overview
As we can see from the signature above, the some() function takes a callback as the first
argument, and an optional second argument. The second argument, if provided, specifies
the this value for invocations of the supplied callback. The some() function runs the
provided callback on each element in the array, and if the callback returns true, then
the some() function stops right away and returns true. If all callback iterations return false,
then some() returns false.
Returns
some() either returns true or false. At least one item in the array must return true when
the callback is applied in order for some() to return true.
array.some() function examples
function jsarrayfuncs(element, index, array) {
return element === 'javascript array functions';
}
var one = ['the good parts', 'the better parts', 'has no parts', 'atwood loves php'];
var two = ['life is good', 'arrays for all', 'node for win', 'javascript array functions'];
console.log(one.some(jsarrayfuncs)); // false
console.log(two.some(jsarrayfuncs)); // true
18. Array.prototype.lastIndexOf()
array.lastIndexOf(searchElement[, fromIndex = arr.length – 1])
Overview
The lastIndexOf() function searches through an array backwards for a supplied value.
Once the function finds that value, it returns the index position of where that value exists in
the array. If you provide the optional second argument to the lastIndexOf() function,
searching will begin from that starting point and go backwards. If you do not supply this
second argument, searching starts at the end of the array. If no match is found, -1 is
returned.
Returns
The highest index position that is less than or equal to the start of the array where the
element is === to the value you are looking for, or -1 if there are no matches found.
array.lastIndexOf() function examples
var starwars = ['Episode 4: A New Hope',
'Episode 5: The Empire Strikes Back',
'Episode 6: Return of the Jedi',
'Episode 1: The Phantom Menace',
'Episode 2: Attack of the Clones',
'Episode 3: Revenge of the Sith',
'Episode 7: The Force Awakens'];
19. Array.prototype.reduceRight()
array.reduceRight(callback[, initialValue])
Overview
The reduceRight() function works just like reduce() with one key
difference. reduceRight()enumerates array elements from right to left (from highest index
to lowest) rather than left to right (lowest to highest).
array.reduceRight() function example
var sum = [0, 10, 20, 30].reduceRight(function (one, two) {
return one + two;
});
console.log(sum); // 60
var flat = [[0, 10], [20, 30, [1, 2, 3, 4]], [40, 50]].reduceRight(function (one, two) {
return one.concat(two);
}, []);
console.log(flat);
// [40, 50, 20, 30, [1, 2, 3, 4], 0, 10]
20. Array.prototype.every()
array.every(callback[, thisArg])
Overview
You can use the every() function to test whether a condition is true for all elements in an
array. As like with most looping functions in JavaScript, you are expected to provide a
callback function which will run on each element in the array from lowest to highest index.
If all iterations return true when the callback runs, then the every() function itself will
return true. If however an interation of the callback returns a false value,
then every() stops right away and returns false.
array.every() function example
function greaterThan100(element, index, array) {
return element > 100;
}
console.log(arr1.every(greaterThan100)); // true
console.log(arr2.every(greaterThan100)); // false
Array.prototype.reverse()
array.reverse()
Overview
The reverse() function does exactly what you think it would do. It reverses the order of the
elements of they array it is applied to. The reverse() function does this right on the original
array, no new array is created or returned. In addition keep in mind that if there are many
references to a particular array in your program, and you reverse that array, all references
now also see an array which has been reversed. Perhaps that is why this function appears
lower on our most useful JavaScript array functions list. Remember, the lower on the list a
function appears, the less times we found it in use in popular open source software.
array.reverse() function example
var javascriptArray = ['eat', 'sleep', 'breathe', 'javascript'];
javascriptArray.reverse();
console.log(javascriptArray);
// ["javascript", "breathe", "sleep", "eat"]
Most Useful JavaScript Array Functions Summary
In this episode we took a look at all of the many useful JavaScript Array Functions you’re
likely to make use of and find helpful during your JavaScript programming. We used a
method of analyzing popular JavaScript source code repositories hosted on Github, the
well known open source software sharing and collaboration website. We found that the
most useful JavaScript functions according to the number of times they were used in
popular JavaScript frameworks to be Array.push(), Array.indexOf(), Array.slice(),
Array.toString(), Array.filter(), Array.join(), Array.splice(), Array.forEach(),
Array.concat(), Array.shift(), Array.unshift(), Array.map(), Array.sort(), Array.pop(),
Array.reduce(), Array.some(), Array.lastIndexOf(), Array.reduceRight(), Array.every(),
and finally, Array.reverse(). It would make sense to memorize as many of these as you
can, or at least be very familiar with the ones that appear at the top of the list.
JavaScript String Functions are the topic of this adventure into programming
JavaScript. There are relatively few functions that you need to be aware of,
however it is helpful to have a good in depth knowledge of how each string
function works in order to get the most out of working with strings in JavaScript.
Just like our tutorial covering useful arrays in JavaScript, this tutorial makes use
of the same approach. We try to decipher which JavaScript string functions are
being used very frequently in the open source ecosystem of frameworks and
libraries. Those that are used frequently are deemed more useful and appear at
the top of the list in this tutorial.
Note that if a string is delimited with double quotes, you can use single quotes inside of the
string. The reverse is true if you are delimiting with single quotes. In that scenario, you can
contain double quotes inside of the string. Of course, you can also use the escape
character \ if you need to bend these rules just a bit.
2. String.prototype.replace()
string.replace(regexp|substr, newSubStr|function[, flags])
string.replace() description
When you want to do a search and replace on a string in JavaScript,
the replace() function is the one you want to make use of. This function searches the
provided haystack, or string, for one or several substrings that match a given pattern or
regular expression. It then replaces those matches with a replacement. You can specify
the global g flag to replace all matches if you like when using a regular expression rather
than a simple string. If global is not specified, only the first match will be replaced. Check
out our tutorial covering regular expressions if you need a refresher on how to use them.
They are a beast! In terms of how powerful they are though, they simply can’t be beat.
Here is where it gets a little dicey, in true JavaScript form. The replacement can not only
be a string like you might expect, it can also be a function.
What replace() returns
The replace() function returns a new string with matches of the string or regular
expression replaced by any replacements made. The string it is called on does not
change, only the return value is modified.
string.replace() function examples
This example of the replace() function looks at the old string, and replaces instances
of javascriptwith JavaScript. We include both the g and i flags in this
example. g indicates that this is a global search and replace, meaning all instances will be
replaced. If we had omitted the g flag, only the first instance would be replaced. The i flag
is for ignoring the case.
var oldstring = 'Programming with string in javascript is fun! ' +
'Old javascript string, not the same as new javascript string';
var newstring = oldstring.replace(/javascript/gi, 'JavaScript');
console.log(oldstring);
// Programming with string in javascript is fun! Old javascript string, not the same as new
javascript string
console.log(newstring);
// Programming with string in JavaScript is fun! Old JavaScript string, not the same as new
JavaScript string
Here we will use replace() to find instances of the characters AAPL in a string of text, and
replace them with the text of Apple. Note that this example works because we include
the i flag modifier which indicates that this is case insensitive.
var oldstring = 'AAPL is a great company with awesome products';
var newstring = oldstring.replace(/aapl/i, 'Apple');
console.log(newstring);
// Apple is a great company with awesome products
When you have portions of your regular expression surrounded by parenthesis, you can
can access that substring match using the $n operator. Let’s see how we do this. In this
following example, we have a regular expression which matches four lowercase letters
followed by a space, four times in a row. Each collection of four characters is surrounded
by parenthesis, so we now have access to the first, second, third, and fourth matches. In
the second example we only use the $4 and $3 instances in mixed order to show how the
matches are replaced according to position.
var regularexp = /([a-z]{4})\s([a-z]{4})\s([a-z]{4})\s([a-z]{4})\s/;
var oldstring = 'aapl goog msft amzn ';
var newstring = oldstring.replace(regularexp, '$4, $3, $2, $1');
console.log(newstring);
// amzn, msft, goog, aapl
The next special character replacement is the $$ operator. This is for inserting a literal
dollar sign into the replacement string. Let’s replace Money! with $ in the replacement
string.
var pattern = /M[aA-zZ]*!/g;
var oldstring = 'Special characters can be used in the replacement string! Money!';
var newstring = oldstring.replace(pattern, '$$');
console.log(newstring);
// Special characters can be used in the replacement string! $
You can also access the part of the string that comes before that matched substring. For
this we will use the $backtick operator. We will find the match of can and replace it with
any text that comes before it.
var pattern = /can/g;
var oldstring = 'Special characters can be used in the replacement string! Money!';
var newstring = oldstring.replace(pattern, '$`');
console.log(newstring);
// Special characters Special characters be used in the replacement string! Money!
Now we will make use of $’ which inserts the text that comes after the matched substring.
We will find the word into, and replace it with any text that comes after that match.
var pattern = /into/;
var oldstring = 'You are turning into a pro with this replace function!';
var newstring = oldstring.replace(pattern, "$'");
console.log(newstring);
// You are turning a pro with this replace function! a pro with this replace function!
Pattern Inserts
$` Takes the part of the string that comes before the substring match and inserts it into the replacement string.
$' Takes the part of the string that comes after the substring match and inserts it into the replacement string.
$n This operator finds the numerical position of the substring match and inserts that particular match in the replacement strin
first argument was a regular expression.
function tickerToName(match){
if(match === 'AAPL'){
return 'Apple';
} else if (match === 'GOOG'){
return 'Google';
} else if (match === 'MSFT') {
return 'Microsoft';
}
}
console.log(newstring);
// Apple Google and Microsoft are really big technology companies.
The replace() function appears right at the top of our list of useful JavaScript string
functions. In looking at some of the examples above we can see why. This function is
incredibly powerful and works with both standard strings, regular expressions,
and custom functions. It is very involved, and there is a lot to understand in order to use
it effectively, most notably understanding regular expressions.
3. String.prototype.toLowerCase()
string.toLowerCase()
string.toLowerCase() description
The toLowerCase() function does exactly what you think it would. It simply returns a new
string that has been converted to all lower case from the old string. The original string is
not changed.
string.toLowerCase() function examples
This is a really simple example.
var oldstring = 'HEY SHORTY, ITS YOUR BIRTHDAY!';
console.log(oldstring);
// HEY SHORTY, ITS YOUR BIRTHDAY!
console.log(newstring);
// hey shorty, its your birthday!
This example has a little bit of a better use case. Let’s build a sluggify function that takes a
string, and turns it into it’s slug form.
var oldstring = 'The Most Popular JavaScript String Functions';
var pattern = /\s/g;
function sluggify(str) {
return str.replace(pattern, '-').toLowerCase();
}
console.log(oldstring);
// The Most Popular JavaScript String Functions
console.log(newstring);
// the-most-popular-javascript-string-functions
4. String.prototype.trim()
string.trim()
string.trim() description
The trim() function removes any whitespace characters from both the beginning and
ending of a particular string.
string.trim() function examples
var oldstring = ' \r \n the string be with you \v \f ';
console.log(oldstring);
// \r \n the string be with you \v \f
console.log(newstring);
// the string be with you
console.log(newstring);
// abcdef
trim() works great for data sanitization and other means of cleaning up data before
operating on it.
5. String.prototype.charAt()
string.charAt(index)
string.charAt() description
The charAt() function stands for character at. You can find the exact location of a given
character in a string when you use this function. It almost reads like, “Tell me the character
at position x”. In order for the charAt() function to do it’s job, you must provide an index
parameter between 0 and one less than the length of the string you would like to perform
the charAt() function on. If the index provided as a parameter is not
between 0 and string.length − 1, this function returns an empty string.
This kinds of works like indexOf() in reverse. With charAt(), you provide a numerical
value, and charAt() tells you the character that lives at that location. With indexOf(), you
provide the character, and indexOf() tells you the index location it lives at.
string.charAt() function examples
var lightsaber = 'Super Powerful Slicing Ability';
console.log(lightsaber.charAt(0));
// S
console.log(lightsaber.charAt(lightsaber.length - 1));
// y
6. String.prototype.charCodeAt()
string.charCodeAt(index)
string.charCodeAt() description
The charCodeAt() function works almost like charAt() except instead of returned the
character at a specific index position, it returns the encoding of the character at a given
position in the string.
string.charCodeAt() function examples
Here we will use the alphabet as a string, and learn the Unicode number associated with
every letter by making use of charCodeAt().
var alphabet = 'abcdefghijklmnopqrstuvwxyz';
console.log(alphabet.charCodeAt(0)); // 97
console.log(alphabet.charCodeAt(1)); // 98
console.log(alphabet.charCodeAt(2)); // 99
console.log(alphabet.charCodeAt(3)); // 100
console.log(alphabet.charCodeAt(4)); // 101
console.log(alphabet.charCodeAt(5)); // 102
console.log(alphabet.charCodeAt(6)); // 103
console.log(alphabet.charCodeAt(7)); // 104
console.log(alphabet.charCodeAt(8)); // 105
console.log(alphabet.charCodeAt(9)); // 106
console.log(alphabet.charCodeAt(10)); // 107
console.log(alphabet.charCodeAt(11)); // 108
console.log(alphabet.charCodeAt(12)); // 109
console.log(alphabet.charCodeAt(13)); // 110
console.log(alphabet.charCodeAt(14)); // 111
console.log(alphabet.charCodeAt(15)); // 112
console.log(alphabet.charCodeAt(16)); // 113
console.log(alphabet.charCodeAt(17)); // 114
console.log(alphabet.charCodeAt(18)); // 115
console.log(alphabet.charCodeAt(19)); // 116
console.log(alphabet.charCodeAt(20)); // 117
console.log(alphabet.charCodeAt(21)); // 118
console.log(alphabet.charCodeAt(22)); // 119
console.log(alphabet.charCodeAt(23)); // 120
console.log(alphabet.charCodeAt(24)); // 121
console.log(alphabet.charCodeAt(25)); // 122
The output above is the Unicode number of each letter of the alphabet in lowercase.
7. String.prototype.toUpperCase()
string.toUpperCase()
string.toUpperCase() description
Just like you think it might, the toUpperCase() function turns a string into an all uppercase
version of itself. Do note that the original string is left untouched, while the returned string
is the all uppercase version.
string.toUpperCase() function examples
var light = 'lightsabers';
var sabers = light.toUpperCase();
console.log(light);
// lightsabers
console.log(sabers);
// LIGHTSABERS
8. String.prototype.match()
string.match(regexp)
string.match() description
The match() function makes use of powerful regular expression patterns. In order
for match() to work, you must pass it one parameter, which is a regular
expression. match() will then use that pattern to find all matches in the given string, then
return an array of any matches. If there are no matches based on the regular expression
you pass in, then match() returns null.
string.match() function examples
var numbersinstring = '50 plus 50 equals 100!'
var result = numbersinstring.match(/\d+/g);
console.log(result);
// ["50", "50", "100"]
console.log(fullurl);
// http://vegibit.com/javascript-string-functions/
console.log(protocol);
// http
console.log(host);
// vegibit.com
console.log(path);
// javascript-string-functions/
9. String.prototype.concat()
string.concat(string2, string3[, …, stringN])
string.concat() description
In JavaScript you can use the concat() function to add strings together. You could also
simply use the + operator, which is also very easy. You can pass as many strings as you
like to the concat() function. Let’s look at a few examples of string.concat() in action.
var firstString = 'JavaScript is ';
var newString = firstString.concat('awesome, ', 'fun, ', 'and useful!');
console.log(newString);
// JavaScript is awesome, fun, and useful!
console.log(five);
// abcdefghijklmnopqrstuvwxy and z
10. String.prototype.substr()
string.substr(start[, length])
string.substr() description
The substr() function looks into a string and extracts a specific number of characters from
that string based on the provided start and length parameters. The start parameter is
where the search for the substring begins, and the length parameter specifies the number
of characters to extract beginning from start. If the length parameter is not provided, all
characters from the start position are extracted from the original string. If the length is 0 or
a negative value, substr() will return an empty string. Finding a string within a string, or
substring, is very common in any programming language. In addition to substr(), you can
also make use of the related substring() and slice() functions which we cover here as
well.
string.substr() function examples
var supercali = 'supercalifragilisticexpialidocious';
console.log(supercali.substr(0, 5));
// super
console.log(supercali.substr(5, 4))
// cali
console.log(supercali.substr(9, 11))
// fragilistic
console.log(supercali.substr(20));
// expialidocious
console.log(supercali.substr(0));
// supercalifragilisticexpialidocious
console.log(tuts);
// Epic JavaScript
console.log(plus);
// String Tutorial
11. String.prototype.split()
string.split([separator[, limit]])
string.split() description
The split() function explodes a string into an array of characters based on a
provided separator. You can optionally limit the number of splits to be found by passing an
integer value as the second argument to the split() function. This is a very useful
function.
In this example, we have all the JavaScript string functions linked together with
the . character as one big string. Using string.split(), we will turn that one string into an
array, with each function name occupying a slot in the array.
string.split() function examples
var oneBigString =
'fromCharCode.fromCodePoint.anchor.big.blink.bold.charAt.charCodeAt.codePointAt.concat.endsWith.' +
'fixed.fontcolor.fontsize.includes.indexOf.italics.lastIndexOf.link.localeCompare.match.normalize.quo
te.repeat.' +
'replace.search.slice.small.split.startsWith.strike.sub.substr.substring.sup.toLocaleLowerCase.toLoca
leUpperCase.' +
'toLowerCase.toSource.toString.toUpperCase.trim.trimLeft.trimRight.valueOf.raw';
console.log(newArray);
// ["fromCharCode", "fromCodePoint", "anchor", "big", "blink", "bold", "charAt", "charCodeAt",
"codePointAt",
// "concat", "endsWith", "fixed", "fontcolor", "fontsize", "includes", "indexOf", "italics",
"lastIndexOf", "link",
// "localeCompare", "match", "normalize", "quote", "repeat", "replace", "search", "slice", "small",
"split", "startsWith",
// "strike", "sub", "substr", "substring", "sup", "toLocaleLowerCase", "toLocaleUpperCase",
"toLowerCase", "toSource",
// "toString", "toUpperCase", "trim", "trimLeft", "trimRight", "valueOf", "raw"]
12. String.prototype.fromCharCode()
String.fromCharCode(num1[, …[, numN]])
string.fromCharCode() description
The fromCharCode() function is used to create a string from Unicode encodings. You pass
one or more integers to the fromCharCode() function as parameters that specify the
Unicode encodings of the characters in the string to be created.
string.fromCharCode() function examples
Here we will pass in a bunch of Unicode numbers to produce a secret message.
var secretcode = String.fromCharCode(69, 118, 101, 114, 121, 116, 104, 105, 110, 103, 32, 105, 115,
32, 65, 87, 69, 83, 79, 77, 69);
console.log(secretcode);
// Everything is AWESOME
13. String.prototype.substring()
string.substring(indexStart[, indexEnd])
string.substring() description
The substring() function has two parameters, those being indexStart and indexEnd. The
indexStart parameter is required and specifies the position of where to start the extraction
of characters. The indexEnd is optional and specifies the location where the extraction of
characters should end. The character that is at the indexEnd position, is not actually
included in the extracted substring. If the indexEnd parameter is not provided, then all
characters from the start position until the end of the string are extracted. A curious
behavior of the substring() function is that if the value of indexStart is greater than the
value of indexEnd, substring() will automatically swap these two arguments!
note: Just like in JavaScript Arrays, JavaScript Strings start at index 0.
string.substring() function examples
var supercali = 'supercalifragilisticexpialidocious';
console.log(supercali.substring(0, 5));
// super
console.log(supercali.substring(5, 9));
// cali
console.log(supercali.substring(9, 20));
// fragilistic
console.log(supercali.substring(20));
// expialidocious
console.log(supercali.substring(0));
// supercalifragilisticexpialidocious
var theForce = 'The force is strong with you because you are AWESOME';
var last8oftheForce = theForce.substring(theForce.length - 8);
console.log(last8oftheForce);
// AWESOME
note: The substr() and substring() functions are almost exactly the same, but there are
some subtle differences. First off, the second parameter of substring() tells JavaScript
where the extraction of the substring needs to stop. This character is not included in the
substring. For the substr() function, that second parameter actually is the number of
characters to return beginning from the start position. So with substring(), you need to
specify the exact index ending location, while with substr() you must specify the length of
the substring to return. If you are not getting the results you expect from one of these
functions, this might be one of the reasons why. In addition to this, substr() does not work
in Internet Explorer 8 and earlier.
14. String.prototype.valueOf()
string.valueOf()
string.valueOf() description
The valueOf() function is a method of JavaScript’s build in String object and returns the
primitive value of a String object as a string data type. The value returned is the same as
you would get from String.prototype.toString().
string.valueOf() function examples
var str = new String('Jumping Jack Flash');
console.log(str.valueOf());
// Jumping Jack Flash
15. String.prototype.slice()
string.slice(beginSlice[, endSlice])
string.slice() description
The slice() JavaScript function takes two parameters. beginSlice is the first parameter,
and endSlice is the second parameter. You may also see these parameters begin referred
to as start and end. beginSlice is a required parameter and specifies the beginning point
of the extraction of the substring. The endSlice parameter is optional. It specifies the
location at which to stop the extraction. The character specified by endSlice is not included
in the extracted substring. If you do not provide the endSlice parameter, all characters
beginning from the beginSlice position will be extracted from the original string as part of
the substring. We can see that the slice(), substring(), and substr()functions all work in
a very similar fashion.
string.slice() function examples
var usForce = 'The Force Is With Us!';
var youforce = usForce.slice(0, 19);
console.log(youforce);
// The Force Is With U
note: The slice() and substring() functions are almost the same. One difference however
is that if the start parameter is greater than the stop parameter, the substring() function
will swap those two parameters. The slice() function has no such ability to swap those
two parameters.
16. String.prototype.indexOf()
string.indexOf(searchValue[, fromIndex])
string.indexOf() description
The indexOf() function is very useful, especially when working with a substring in
JavaScript. This function returns the position of the first occurrence of a given value in a
string. If that value is not found in the string, then indexOf() will return -1.
string.indexOf() function examples
var email = 'gmail@google.com';
var index = email.indexOf('@');
console.log(index);
<script>
function breakOnAtSymbol() {
var email = document.getElementById('textEmailAddress').value;
document.getElementById('textEmailPart').value = emailpart;
document.getElementById('textDomainPart').value = domainpart;
}
</script>
You did not instantiate any type of class whatsoever. All you did was call a function, and
again, as if by magic, a brand new object was created and returned to you in one
step.
The second thing that happens is that the new object gets [[Prototype]] linked. Just what
does that mean? It means that HouseOne has a prototype linkage to House.prototype. Let’s
see how this works in code.
House.prototype.whatcolor = function () {
console.log('The color of this house is ' + this.color);
};
HouseOne.whatcolor();
// The color of this house is Red
The whatcolor() method worked only because HouseOne has a prototype linkage
to House.prototype. So we can see that using the new keyword does create this
prototype linkage automatically for us. This is how we do inheritance in JavaScript. It
makes sense to refer to it as inheritance, since that is what we are used to in traditional
object oriented languages. What is really happening here though, is that JavaScript
is delegating the function call of whatcolor() up the prototype chain. It works almost like
lexical scoping, where if JavaScript does not find the variable in the local scope, it will
move one step outside of the local scope and look for a particular variable there. With
function calls, it works in a similar way. House tries to call the whatcolor() function, notices
that it does not have a whatcolor()function, then sends the request up the prototype
chain. It turns out House.prototype does in fact have that function, so alas, it does the
function call for us. Code reuse in JavaScript happens via a bottom to top sequence of
delegation, whereas what we are all familiar with is a top / down sharing via inheritance in
classical object oriented programming. The end result is similar, but the internal processes
in the language are very different. Let us now take a look at the third thing that happens
when you use the new keyword on a function in JavaScript.
3. The brand new object that was created gets bound to this for the purposes of that function call.
As we know, during the call of a function by use of the new keyword, a new object is
created. Within the function that was called, this now refers to the newly created object.
Learn all about the JavaScript this Keyword if you are not familiar. Let’s see this third
rule in action now.
function House(color) {
this.color = color;
};
House.prototype.whatcolor = function () {
console.log('The color of this house is ' + this.color);
};
HouseOne.whatcolor();
// The color of this house is Red
HouseTwo.whatcolor();
// The color of this house is Blue
The reason why we get the right color back in the example above is because of
the this binding. We call the House function two times with the new keyword. In the first
instance, this points to the first object we created via new House('Red');. In the second
instance, this points to the second object created in our program via var HouseTwo = new
House('Blue');. Finally, we can examine how this is automatically returned if there is no
other object being returned from that function call.
console.log(HouseOne.color);
// Red
The function returns this, the newly created object. We proved this by checking
if HouseOne is an instance of House, and we do get true. Let us now simply change the
function ever so slightly by adding a return statement to it.
function House(color) {
var obj = {
color: 'Green'
};
this.color = color;
return obj;
};
console.log(HouseOne.color);
// Green
As we can see here, the returned object is now no longer an instance of House! It is simply
a plain JavaScript object returned from that function call. So we can see, when using
the new keyword on a function in JavaScript, you will get different results based on whether
that function explicitly returns an object or not. JavaScript!
Four Things That Happen When The JavaScript new Keyword Gets Called With
A Function Call Summary
The behavior of the new keyword in JavaScript is insane. This article is as much to help the
author, as it is to help the reader. In order to use JavaScript effectively, or even be able to
read source code with understanding, you need to really understand
how new and this work. What makes this difficult is that most of us start programming
JavaScript and expect new to instantiate an object from a class, like Java or PHP. In
JavaScript, new has nothing to do with classes. It has nothing to do with instantiating
objects from classes. In fact, JavaScript has no classes. In JavaScript, new magically turns
any function it is used on into a constructor call. This still does not have anything to do with
classes! In addition to that, new modifies the behavior of the typical JavaScript function call
in four distinct ways which we covered above. Hat tip to getify for helping clear things up
with regard to new and this!
Much like nailing jelly to a wall, the thiskeyword in JavaScript is a bit like a
whack a mole game. Each time you think you’ve got it, you realize
that this might not be referring to what you thought it was! Once again you find
yourself trying to decipher how and what thisis doing for you in your JavaScript
program. In JavaScript, there are four key rules to memorize about how to
determine what this is referring to. There is also an order of precedence to
these rules. In this tutorial, we’ll examine exactly what this does for you in
JavaScript, and memorize the four rules that determine it’s context. Let’s dig in
now.
this refers to an object
One thing we can be confident of, is that no matter what, this always is referring to an
object. It will never be referring to a primitive value like a boolean, string, or number. It will
always be an object that it refers to.
Function Context
Before we get to the rules that determine how this works, we first need to understand a
little bit about how functions in JavaScript work. Mainly, we need to be aware of the
following:
Every function, while executing, has a reference to it’s current execution context. The current
execution context is referred to as the this keyword.
In other words, this is what object is associated with the current function call
With this in mind, we must be aware of the single most important thing to look for when
dealing with this in JavaScript. What we are referring to is how the function is called, when
it is called. In other words, must pay special attention to the call site of that function. For it
is the call site that determines what this is bound to. In essence, this acts as a type of
dynamic scoping mechanism in JavaScript.
In order to demonstrate this, we will create several different JavaScript objects. Each
object will have a property named prop1, and a property named decoder.
The decoder property will have a reference to a function named thisdecoder() on all
objects. We will see that the value contained in prop1 will depend entirely on the call
site of the thisdecoder() function.
2. Explicit Binding
Explicit Binding is handled with the apply(), call(), and bind() methods of a function
object. In JavaScript, functions are objects, therefore functions themselves can have
methods. The first two methods are similar, in that the first argument provided to them is
the object to which you want the this keyword to be bound to. apply() and call() are
almost the same thing, but the difference between them is that call() accepts an
argument list, while apply() accepts a single array of arguments. In our example, we only
pass one argument, the object we want bound to this, so in our
case apply() and call() work identically.
bind() is a little more confusing. It actually creates an entirely new function, which is then
itself callable. When you call that new function, the this keyword is bound to the provided
argument which was given to the bind() invocation.
function thisdecoder() {
console.log(this.prop1)
};
var objectone = {
prop1: 'This is a string in object ONE.',
decoder: thisdecoder
};
var objecttwo = {
prop1: 'This is a string in object TWO.',
decoder: thisdecoder
};
var objectfour = {
prop1: 'This is a string in object FOUR.',
decoder: thisdecoder
}
var objectthree = {
prop1: 'This is a string in object THREE.',
decoder: thisdecoder
};
//---Explicit Binding---//
objectone.decoder.apply(objectthree);
// This is a string in object THREE.
objecttwo.decoder.call(objectone);
// This is a string in object ONE.
3. Implicit Binding
Implicit binding is pretty easy. Implicit binding happens when you call a function as a
property or method of a given object. In our example below, all objects have
a decoder property. Furthermore, each of these properties simply reference the same
function called thisdecoder(). None of the given objects owns the thisdecoder() function
any more than the other, they all simply have peer references to the same function. You
could say we have put a reference to a function on an object. The implicit binding rules
states that the object at the call site, also known as the base object, context object, or
containing object, becomes the binding for the this keyword.
function thisdecoder() {
console.log(this.prop1)
};
var objectone = {
prop1: 'This is a string in object ONE.',
decoder: thisdecoder
};
var objecttwo = {
prop1: 'This is a string in object TWO.',
decoder: thisdecoder
};
var objectfour = {
prop1: 'This is a string in object FOUR.',
decoder: thisdecoder
}
var objectthree = {
prop1: 'This is a string in object THREE.',
decoder: thisdecoder
};
//---Implicit Binding---//
objectfour.decoder();
// This is a string in object FOUR.
objectthree.decoder();
// This is a string in object THREE.
objecttwo.decoder();
// This is a string in object TWO.
objectone.decoder();
// This is a string in object ONE.
var objectone = {
prop1: 'This is a string in object ONE.',
decoder: thisdecoder
};
var objecttwo = {
prop1: 'This is a string in object TWO.',
decoder: thisdecoder
};
var objectfour = {
prop1: 'This is a string in object FOUR.',
decoder: thisdecoder
}
var objectthree = {
prop1: 'This is a string in object THREE.',
decoder: thisdecoder
};
//---Default Binding---//
thisdecoder();
// This string lives in the global scope.
• 3. Implicit Binding
objectfour.decoder();
objectthree.decoder();
objecttwo.decoder();
objectone.decoder();
In this tutorial, we will make use of VueJS and PHP to build a really cool
keyword density tool. On the Vue side, we’ll make use of components,
templates, and root elements, and more. We will use PHP to generate the form
we need, as well as to handle form processing, in addition to making use of
the substr_count() function to provide the data we need. Let’s see how we
can do this, it should be fun.
if (strstr($keyword, ',')) {
$i = 1;
$keywords = explode(',', $keyword);
?>
<script>
// fill the data that populates the component
var action = new Vue({
el: '#findkeywords',
data: {
searchQuery: '',
keywordcounterColumns: ['term', 'count'],
keywordcounterData: [
<?php
foreach ($keywords as $keyword) {
echo ' { term: "' . $keyword . '", count: ' . substr_count($haystack,
$keyword) . ' },';
}
?>
]
}
});
</script>
<?php
} else {
?>
<table class="table table-hover">
<thead>
<tr>
<th style="cursor:hand;"> Term <span class="arrow asc"> </span></th>
<th style="cursor:hand;" class="active"> Count <span class="arrow asc"> </span></th>
</tr>
</thead>
<tbody>
<tr>
<td><?php echo $keyword ?></td>
<td><?php echo substr_count($haystack, $keyword); ?></td>
</tr>
</tbody>
</table>
<?php
}
}
?>
Sort By Term
After submitting the data to our application, we can click on the Term table header to sort
our results via Term name.
Sort By Count
After submitting the data to our application, we can click on the Count table header to sort
our results via count.
window.setTimeout(function () {
withoutclosurehtml.innerHTML += '<br>' + withoutClosure();
}, 500);
Click Clear
710
211
return function () {
return date.getMilliseconds();
}
}
var withclosurehtml = document.getElementById('withclosure');
var closure = withClosure();
withclosurehtml.innerHTML = closure();
window.setTimeout(function () {
withclosurehtml.innerHTML += '<br>' + closure();
}, 500);
Click Clear
141
141
return {
nestedfunction: nestedfunction
}
};
window.setTimeout(function () {
withclosurehtml2.innerHTML += '<br>' + closure.nestedfunction();
}, 500);
Click Clear
646
646
Final Example
As one final example, we’ll simply add a few more calls to
the date.getMilliseconds()method and demonstrate that it is accessing the same date
object each time. This is a good example of how closure will persist those variables you
need for as long as is required. We could add a hundred calls to
the date.getMilliseconds() method and the same result would be returned every time.
var withClosure3 = function () {
var date = new Date();
var nestedfunction = function () {
return date.getMilliseconds();
};
return {
nestedfunction: nestedfunction
}
};
window.setTimeout(function () {
withclosurehtml3.innerHTML += '<br>' + closure.nestedfunction();
}, 500);
window.setTimeout(function () {
withclosurehtml3.innerHTML += '<br>' + closure.nestedfunction();
}, 1000);
window.setTimeout(function () {
withclosurehtml3.innerHTML += '<br>' + closure.nestedfunction();
}, 1500);
window.setTimeout(function () {
withclosurehtml3.innerHTML += '<br>' + closure.nestedfunction();
}, 2500);
Click Clear
894
894
894
894
894
There are many ways to structure JavaScript code using various design
patterns in an effort to produce software that is easier to reason about as well
as reusable and maintainable. One such pattern is the prototype pattern. As we
know, JavaScript itself uses prototyping as a means of augmenting the built in
objects. With the prototype pattern, you can directly extend JavaScript objects
and arrange your code in such a way as you might with a more traditional
object oriented approach that you might find in Java or PHP. Let’s have a closer
look at the JavaScript Prototype Pattern now.
Drawbacks
That last point can almost be seen as a benefit actually. The reason is, the constructor is
going to contain all the variables. Each time a new instance is made, you’ll get a fresh set
of variables to work with. This is how you can have an instance of a house where it’s color
is red, and another instance of a house where it’s color is blue. The functions reside in the
prototype section of the pattern, and the big benefit here is that no matter how many
instances of the particular constructor or “class” you are dealing with, each individual
function is loaded only one time into memory. With these quick examples of benefits and
drawbacks, let’s have a look at the structure of a prototype pattern.
Click Clear
ProdecoTech Bicycle Moving forward at 100 percent speed!
When you run this example code, you can see it outputs the result based on the data we
pass in. We used the new keyword to create a new instance of a Bicycle, passing in the
brand of ProdecoTech, which is a really cool electric bicycle brand. Then, we can call
methods off of that new object we have. We demonstrate this by
calling bike.goForward() passing in a 100 percent value. If all works correctly, we
see ProdecoTech Bicycle Moving forward at 100 percent speed! output to the screen. Now
that you have a Constructor, you can new up as many different instances as you might
need. This is analogous to creating new objects in class based languages. Let’s try it out.
var bike = new Bicycle('ProdecoTech');
var speed = bike.goForward(100);
Click Clear
ProdecoTech Bicycle Moving forward at 100 percent speed!
Specialized Bicycle Moving forward at 90 percent speed!
Cannondale Bicycle Moving forward at 75 percent speed!
When we set up the Function Prototype for our Bicycle, we assigned an object literal to the
prototype. An object literal consists of one or many key value pairs. So far we only have
one key, and one value. The key is ‘goForward’ and the value is an anonymous function.
What this means is that all objects that are newed up from this Bicycle constructor will
have access to that particular method. If you have a bicycle, and all you can do is go
forward, you may get into trouble when it comes time to stop. It would be wise that all
bicycles have the ability to slow down or stop. We can add this to all bicycles by simply
extending their functionality by adding an additional key value pair to the object literal
assignment in the function prototype. All you have to do is add a comma after the first key
value pair and then add another key value pair as needed. Let’s see.
Extending The Prototype
Bicycle.prototype = {
goForward: function (percent) {
percent = ' Bicycle Moving forward at ' + percent + ' percent speed!';
return percent;
},
With our function prototype updated, we should be able to have any instance of a Bicycle
make use of either method.
var bike = new Bicycle('ProdecoTech');
var speed = bike.goForward(70);
Click Clear
ProdecoTech Bicycle Moving forward at 70 percent speed!
Specialized Bicycle Applying 60 brake pressure. Slowing down now.
Cannondale Bicycle Applying 75 brake pressure. Slowing down now.
We can see that it is working quite well now for all bicycles.
// Define a constructor //
myNamespace.Bicycle = function (brand) {
this.brand = brand;
};
// Set the prototype //
myNamespace.Bicycle.prototype = {
goForward: function (percent) {
percent = ' Bicycle Moving forward at ' + percent + ' percent speed!';
return percent;
},
Cons
// private variables
// private functions
return {
// public functions
};
};
There are a few things to note about this pattern. The first is that you see we apply an
uppercase to the name of the object when we define the module. This is a convention to
indicate that we should use the new keyword on it when we go to make use of this module
in our code at a later time. The very first section inside of the anonymous function we have
are where the private variables and functions would reside. Inside the anonymous function,
we can see a return statement that returns on object literal. Anything contained in this
returned object will be public. Without getting too fancy, we can summarize the pattern as
having three main sections.
Module Pattern Sections
• The Constructor (The named module object and function assignment, may or may
not take parameters)
• The Private Members area (everything that comes before the return keyword)
• The Public area returned by the object literal (anything in the returned object is
public)
With that, let’s see an actual example demo of this pattern now.
// Constructor Declaration (Section 1)
var Tesla = function (model) {
version = model;
// Public Members
// Return object literal (Section 3)
return {
gofast: function () {
return 'Tesla ' + version + ' Now going ' + speed_checker(version) + ' Speed!';
},
slowdown: function () {
return 'Applying brakes to slow down from ' + speed_checker(version) + ' Speed.';
},
autodrive: function () {
return 'Time for a nap. Engaging autodrive.'
}
}
};
Click Clear
Tesla Model 3 Now going Ludicrous Mode Speed!
Applying brakes to slow down from Ludicrous Mode Speed.
Time for a nap. Engaging autodrive.
roadster.version; // undefined - can not access private area variables and functions
roadster.speed_checker; // undefined - can not access private area variables and functions
roadster.speed_checker(); // TypeError: roadster.speed_checker is not a function
return {
// alias to functions and vars
// you want to make public
};
}();
This little outline we have above is an example structure of the revealing module pattern.
At first glance, it does indeed look quite similar to the module pattern that we already had a
look at. Can you spot what is different? Well first off, the name of the module is in
lowercase. This is not an actual requirement, but it is a good idea from a conventions
standpoint, as it gives an indication that the newkeyword is not required with the revealing
module pattern. The reason no new keyword is required is because of those two little
parenthesis after the function declaration. This means it is a self-calling function. The
biggest difference between the module pattern and the revealing module pattern however
is in fact in the return statement. Recall that in the module pattern, we defined our public
functions right in the returned object literal. With the revealing module pattern, there is no
need to do this! You can simply define all of your variables and functions in one place, then
for any of those that you want to make public, you simply give them an alias in an object
literal and return that instead. Let’s go ahead and refactor one of our prior examples to
make use of the revealing module pattern.
The Revealing Module Pattern in Action
var tesla = function (model) {
var version, speed_checker, gofast, slowdown, autodrive;
version = model;
speed_checker = function (version) {
if (version == 'Model 3') {
return 'Ludicrous Mode'
} else if (version == 'Roadster') {
return 'Maximum Plaid'
}
};
gofast = function () {
return 'Tesla ' + version + ' Now going ' + speed_checker(version) + ' Speed!';
};
slowdown = function () {
return 'Applying brakes to slow down from ' + speed_checker(version) + ' Speed.';
};
autodrive = function () {
return 'Time for a nap. Engaging autodrive.'
};
return {
gofast: gofast,
slowdown: slowdown,
autodrive: autodrive
}
}('Model 3');
tesla.gofast();
tesla.slowdown();
tesla.autodrive();
Click Clear
Tesla Model 3 Now going Ludicrous Mode Speed!
Applying brakes to slow down from Ludicrous Mode Speed.
Time for a nap. Engaging autodrive.
Note the lowercase module name, and the immediate parenthesis after the function which
makes it self invoking. This approach creates a singleton which is one single object in
memory. Note that when we are calling methods in this case, we are calling them right on
that singleton instance. For example tesla.gofast() instead of separate instances
like model3.gofast() and roadster.gofast(). You may find this more limiting than when
we were able to create new instances at will when we provided a demo of the module
pattern. Fear not!
Use new with the Revealing Module Pattern if you like!
You can still make use of the new keyword with the revealing module pattern if you like.
Simply leave off the immediately invoking () parenthesis after the module declaration,
change the module name to lowercase (optional), then new up at will. Let’s test that
approach out now.
var Tesla = function (model) {
Click Clear
Tesla Model 3 Now going Ludicrous Mode Speed!
Applying brakes to slow down from Ludicrous Mode Speed.
Time for a nap. Engaging autodrive.
2 blastoff: gofast,
3 slowdown: slowdown,
4 autodrive: autodrive
5}
With that one small change, you can now call code such
as model3.blastoff() and roadster.blastoff(), and behind the scenes, it is actually
the gofast() function providing the implementation for you. It is a simple method of
creating aliases for the functions you want to make public. Name them however you like,
as long as they make sense to you.
Bike.prototype = function () {
// section 2
// all functions get
// defined here
return {
// section 3
// return key value pairs
// of functions you would
// like to make public
};
}();
Here we have the basic outline of the revealing prototype pattern. The pattern roughly
breaks down into 3 different sections as shown. In section 1, we have a Constructor. Inside
of the constructor is where all of the variables for your object get defined. These variable
assignments will make use of the this keyword in a similar was as to how you might with
PHP. Section 1 can be thought of as a state container of sorts.
Section 2 is where we would define the functions we want to make use of and as we can
see, this is in the prototype of our object. Recall that in the prototype pattern, we actually
assigned an object literal to the prototype. In the revealing prototype pattern, we no longer
do it this way. We instead assign a function to the prototype, and then immediately invoke
it. This is how we are able to emulate the concept of public and private members in
JavaScript. Now in section 2, you can consider anything that gets defined as private.
Section 3 is the final piece of the revealing prototype pattern, and this is where we use the
key/value pairs within an object literal to denote what we would like to make public. So if
you defined 10 functions in section 2, and now you want to make 3 of them public, you
simply reference them in section 3. The key of each key/value pair is the name external
callers of the code will reference the functions by. The value in these key/value pairs is the
exact name of the function defined in section 2 for which you would like to make public. To
avoid confusion, many times it makes sense to simply have the key/value pairs go by the
same name.
The revealing prototype pattern makes use of the new keyword in as much as if you want to
make use of your defined object, you’re going to have to new it up. This differs from the
revealing module pattern where everything operates as a singleton. In this pattern, you can
new up as many instances as you need to make use of. The benefits however is that any
functions defined in section 2 are immediately available to any new instance you create.
Let’s see another example of the revealing prototype pattern.
Electricbike.prototype = function () {
// Private members Section 2
var engangemotor = function () {
return 1;
},
applythrottle = function (mode) {
if (engangemotor() == 1) {
return 'Moving forward via ' + mode + ' mode.';
}
},
applybrakes = function (percent) {
return 'Applying brakes at ' + percent + ' percent.';
};
Click Clear
Red Haibike Moving forward via Pedal Assist mode.
Applying brakes at 50 percent.
Underscore.js is the widely popular JavaScript library that provides a rich set of
utility functions for working with the JavaScript language. Unlike PHP,
JavaScript does not have thousands and thousands of built in functions to
make working with data easier. Underscore fixes this by providing various
functions that make it easier to deal with JavaScript Objects, Arrays, and
Functions. Underscore.js is typically included in projects to offer an approach to
coding in JavaScript that is both easier and more expressive than you would
find with native JavaScript. You might consider Underscore as the missing
functions that never were in JavaScript. In this tutorial, we’ll take a look at
the map function in Underscore for working with both arrays and objects.
_.map()
The map function is used to iterate over an array and transform that array into another
array. This first example snippet of the map function in action will demonstrate this for us. If
you click the button to run the code, we can see that Tesla, Leaf, Volt, and Bolt are
mapped from an array. When you call map and pass in electric_cars, the function gets
applied to each item in that array. The map function creates a new array from the return
value of the iterator function. Anytime you need to modify an array into a new one by
applying a function to each element in the array, map is the function to reach for.
Array
var electric_cars = ['Tesla', 'Leaf', 'Volt', 'Bolt'], m;
Click Clear
Tesla is mapped from an array.
Leaf is mapped from an array.
Volt is mapped from an array.
Bolt is mapped from an array.
This next example is more in the style of a declarative or functional approach. This is
because we do not use an anonymous function as the iterator. In fact, less anonymous
functions is probably a good thing, since anonymous functions make things very difficult to
debug at a later time. Here we can see an array of fruits, along with a function of eat. To
be fair, it is a variable that holds a function. What this creates is a new array of fruits as
they are eaten. Some people like this approach since it is fairly easy to decipher what is
happening in the code. We map the fruits through the eat function, then iterate over the
new values to display to the page.
Pass Function
var fruits = ['Banana', 'Blueberry', 'Peach', 'Plum'], eat, ate;
Click Clear
Eating a Banana!
Eating a Blueberry!
Eating a Peach!
Eating a Plum!
This final example of the map function in Underscore shows us how much some pretty cool
electric bicycles cost. It begins with a data object, and within that is an array
of electricbikes. Further down, there is a bikeinfo function which accepts a bike as a
parameter. Inside of this function is another function of getBikeInfo and when it gets
called, a string is returned based on the bike that has been passed in. Finally we see the
call to the map function, and data.electricbikes is passed in as the first parameter. At this
time, the anonymoust iterator function loops through and creates a new bikeinfoobject
while passing in the value. What results in the m variable is an array of bikeinfo objects
and we then just log it out to the page for display. As we can see the map function provides
the ability to take an existing array and transform it into a new array where changes have
been made.
to Object Array
var data, bikeinfo, m;
data = {
electricbikes: [
{brand: 'Easy Motion', model: 'Big Bud Pro', cost: 3499},
{brand: 'Haibike', model: 'XDURO FS RX 27.5', cost: 4900},
{brand: 'IZIP', model: 'E3 Path Plus ', cost: 2299},
{brand: 'Rad Power Bikes', model: 'RadRover ', cost: 1499}
]
};
return {
getBikeInfo: getBikeInfo
};
};
m = _.map(data.electricbikes,
function (value, key, list) {
return new bikeinfo(value);
});
Click Clear
The Easy Motion Big Bud Pro costs 3499!
The Haibike XDURO FS RX 27.5 costs 4900!
The IZIP E3 Path Plus costs 2299!
The Rad Power Bikes RadRover costs 1499!
Click Clear
Element: Tesla, Index: 0, List Length: 4
Element: Nissan, Index: 1, List Length: 4
Element: Chevy, Index: 2, List Length: 4
Element: Subaru, Index: 3, List Length: 4
Click Clear
The value is One where the key is FirstKey
The value is Two where the key is SecondKey
We can see that when we call the each function, TechCompanies.names is passed in as the
first argument to the function. This object also has a nested function which we can see is
named doStuff. We make use of that familiar iterator function which takes in the element,
index, and list. Notice that after the iterator function we in fact pass in TechCompanies as
the context. This binds the TechCompanies object to the this keyword inside the iterator.
See how that works? This is what makes it possible to make the call to this.doStuff() in
the iterator, and it knows where to find that function. If there was no context passed,
the this keyword would be referencing the iterator function and that is not what we want in
this case.
var TechCompanies;
TechCompanies = {
names: ['Microsoft', 'Google', 'Amazon', 'Apple'],
doStuff: function (company) {
return company + ' creates great products.';
}
};
All great reason to go out and pick yourself up a nice Tesla. So this example makes use of
two objects. The first object is the features object, and that holds all of the features of a
cool car. The salesperson object contains functions such as getPitch and sellCar. In the
call to each, we iterate over the features object, then again set up an iterator function as
the second argument. We don’t finish there however, as we also pass in salesperson as
the context to the each function. Therefore when we make a call to this.sellCar in the
iterator, it knows to go look for that function inside the salesperson object since this is what
was passed as the context.
var features, salesperson;
features = {
one: 'Auto Pilot',
two: 'Summons Feature',
three: 'Ludicrous Mode'
};
salesperson = {
getPitch: function () {
return 'This Tesla has ';
},
sellCar: function (msg) {
return this.getPitch()
+ msg;
}
};
In this ongoing look at Underscore JS, we’ll take a look at the some function. It
bears a close resemblance to the find function. The somefunction has a
signature of _.some(list, [predicate], [context]). What it does is to scan
the list parameter for any items that contain a truthy value and return true if
this is the case. This is the default behavior without passing the optional
predicate function. If you provide a predicate function, some will return true for
any items in the list that pass the test of the predicate function. Let’s have a
look at how to make use of the some() function now.
Mixed Array Example
This first example will use examine the contents of an array that has a combination
of truthy and non truthy values. When we run this example code, we are in fact returned
the true value since even though the array contains non truthy values, it also has at least
one truthy value so that returns a true result.
var values = [true, 1, null, 'yes', false];
Click Clear
Are some values "truthy" in the array?
true
Click Clear
Are some values "truthy" in the array?
true
Click Clear
Are some values even in the array?
true
Click Clear
Are any cars electric?
true
Click Clear
Collections listOne and objectOne are not valid when calling _.some() over
them.
Collections listTwo and objectTwo have at least one valid item and they are
valid when calling _.some() over them.
Click Clear
2 is the first even number.
Click Clear
1 is the first odd number.
Click Clear
1 is the first number less than 10.
Click Clear
2 Search Engine Websites
3 Social Network Websites
2 Shopping Site Websites
4 News Site Websites
This Underscore JS tutorial will focus on the Underscore sortBy function, which
works with both JavaScript objects and JavaScript arrays. Like the other
tutorials that offer code examples we can run, so too will we offer several
examples of the sortBy() function here. We’ll look at sorting an integer array,
sorting string arrays, sorting by the property name of an array of objects, as well
as setting up custom sort criteria. Let’s have a look at the
Underscore sortBy() function now. (note: visit http://vegibit.com/underscore-js-
sortby-function/ for interactive examples)
Click Clear
Sort odd numbers first:
1
3
5
7
9
2
4
6
8
10
Click Clear
Sort by length of name:
React
jQuery
Angular
Backbone
Underscore
Click Clear
Bikes sorted by brand:
Anferro
Benelli
Bh Easy Motion
Haibike
Izip
ProdecoTech
Click Clear
Calculating: 1 + 2
Calculating: 3 + 3
Calculating: 6 + 4
Calculating: 10 + 5
Calculating: 15 + 6
Calculating: 21 + 7
Calculating: 28 + 8
Calculating: 36 + 9
Calculating: 45 + 10
All numbers equal:
55
Click Clear
Total price to go fishing: $159
Reduce Object Array With Anonymous Object Example 3
In this third example of the reduce function in Underscore, we make use of an anonymous
object. In this example, we’ll hit the slopes instead of the lakes. The data structure is
similar, but instead of fishing supplies, we have supplies to go skiing. The call
to _reduce() is similar as well. What is different is how we set up the return statement.
Instead of returning a single value, we return an object which has a key of price and a
value of memoizer.price + value.price. Just like the prior example, a running tally of the
prices within the array is calculated. To see the final result, we can simply
access total.price, which is exactly what we do when logging out the data.
var data = {
supplies: [
{item: 'New Skis', price: 1200},
{item: 'Lift Ticket', price: 75},
{item: 'Lunch', price: 25},
{item: 'Gas for car', price: 30}
]
};
Click Clear
Total cost to go skiing: $1330
Click Clear
Are all arrayvalues "truthy"?
true
false (via type coersion)
Are all arrayvalues "true"?
false (via ===)
_every() function example 3
Enough with the falsehoods we say in this third example. Here we’ll just fill up an array
with 3 boolean true values. Running the code on various types of checks using
both == and === produces a trueresult.
var arrayvalues = [true, true, true];
Click Clear
Are all arrayvalues "truthy"?
true
true (via type coersion)
Are all arrayvalues "true"?
true (via ===)
Click Clear
Are all arrayvalues "truthy"?
true
Do all arrayvalues == "true"?
false
Are all arrayvalues "true"?
false
Are all arrayvalues even?
false
var object2 = {
property1: null,
property2: true
};
Click Clear
Collections arraylist1 and object1 are valid when calling _.every() over them.
Collections arraylist2 and object2 do not have all items valid so they are not
valid when calling _.every() over them.
Click Clear
Collections arraylist1 and object1 are valid when calling both _some() and
_.every() over them.
In Underscore, the filter function provides the ability to filter out some values
based off of a Tester function that you pass it. The Tester function is more
formally declared as the predicate. The concept is similar to many of the
Underscore functions we have covered so far. The official signature of filter is
_.filter(list, predicate, [context]) and it returns an array with all the items from the
list collection that satisfy the test condition found in the predicate function.
(note: visit http://vegibit.com/how-does-the-filter-function-work-in-underscore-js/
for interactive examples)
Integer Array
In this first example we have a collection of integer values holding various numbers
between 10 and 100. We also have the evenTester, oddTester, greaterThan75, and
lessThan50 predicate functions defined. Like many other Underscore functions, we call the
main function, in this case filter, and pass the list of values as the first parameter and the
predicate function as the second parameter. In fact, you could create an entire library of
these different predicate testing functions and use them as you may see fit. When you click
to run the example code here, we can see that we have filtered out all of the values that do
not match the provided Tester function. The result is a list of Even numbers, Odd numbers,
Numbers greater than 75, and less than 55.
var values = [10, 21, 32, 43, 54, 65, 76, 87, 98, 100],
Click Clear
Even numbers: 10,32,54,76,98,100
Odd numbers: 21,43,65,87
Numbers Greater Than 75: 76,87,98,100
Numbers Less Than 50: 10,21,32,43
Object Array
This second example will test out the filter function using an Object Array. Again we have
set up an array of values and this time around we have bicycle, model, and price. After this
we have set up our testing, or predicate, functions to do the work for us. The main
difference from the integer array example is that since we have an object array, we need to
know which property of the object will be used in the testing function. In looking at the
evenTester function, we can see that we tap into value.price instead of just the value that’s
coming into the function. Pretty much everythig else works in a similar manner. The testing
functions are a little bit different, only in that we are using different criteria for testing.
var values = [
{bicycle: 'BH', model: 'Evo Jumper 27.5', price: 4399},
{bicycle: 'Haibike', model: 'Sduro FullFatSix', price: 4059},
{bicycle: 'ProdecoTech', model: 'Phantom', price: 2199},
{bicycle: 'Specialized', model: 'Turbo', price: 5900}
],
Click Clear
Even prices:
5900
Odd prices:
4399
4059
2199
Prices Greater Than 4000:
4399
4059
5900
Prices Less Than 4000:
2199
In this Vue.js tutorial, we’ll create a new Vue.js powered application that is a
little more ambitious than what we have covered so far. Here, we will build an
Internet Protocol version 4 javascript subnet calculator. The subnet calculator
accepts an IP address as well as a subnet mask. From these two inputs, the
application dynamically calculates the Network Address, the First Host, the Last
Host, the Broadcast Address, the Total Hosts, and more. Let’s check it out!
(source code and working application at http://vegibit.com/vuejs-subnet-
calculator/ )
When you manually type an IP address into the application, everything updates
dynamically. Watch all fields of the application update on the fly, powered by Vue.js.
2. Click on the up or down number selectors.
Each of the IP address input fields has up and down arrow number selectors. By clicking
up or down in one of the fields, you can increment or decrement the number value by one.
Just like the other ways to update the application, all of the associated calculations update
in real time thanks to VueJS. Note as you click the up and down arrow, the binary value
immediately below updates in real time. So Cool!
3. Click the binary bits of the IP Address.
Instead of manually typing an IP address, you can click on the bits of the IP address below
the decimal format. Notice that when you hover over a particular bit, the value of the bit
position is highlighted. So if we click on the first bit of the fourth byte, it turns this bit on,
and it’s value of 128 is added to the total value of the decimal IP address. In this octet, the
most significant bit is set with a value of 128 and the least significant bit is set with a value
of 1. This gives us the total value of 129. Again, all other fields in the application will
update automatically as you click, all via VueJS.
4. Click the bits of the Subnet Mask.
In order to update the subnet mask, we can click on the binary bits of the subnet mask.
Here, we click the 25th bit on the subnet mask, and this turns that bit to 1 adding a value of
128. Notice that the subnet mask bit length updates automatically as well as the total
number of network hosts available. With a subnet mask of 255.255.255.128, you will have
access to 126 available IP addresses for your local area network. You’ll notice that the
subnet mask decimal input fields are grayed out. You can only update the subnet mask by
clicking on the actual bits of the binary mask. This is by design, since each byte of a
subnet mask can only be the values of 128, 192, 224, 240, 248, 252, 254, and 255.
Let’s find out the binary value of 192, the first byte of our IP address. Here is how you do
that. You always start with the most significant bit, then ask yourself: Does 128 fit into 192?
Yes it does, so we need to set that bit.
This now gives us a decimal value of 128, but we want 192. Now, you must subtract 192 –
128, and that is 64. So we have a value of 64 that we must account for. Again we ask:
does 64 go into 64? Yes it does, so we must also set this bit.
Success! We now have a decimal value of 192 because 128 + 64 = 192. Now we can see
that if you have an 8 bit binary number with the first two bits set, then it’s equivalent
decimal number is 192. So 192 in decimal is the same as 11000000 in binary.
The second byte of our IP address has a decimal value of 168, let’s figure out it’s binary
value. First, does 128 go into 168? Yes it does so we must set that bit.
This gives us a value of 128, but we need 168. So we subtract 168 – 128 and arrive at 40.
Ok, we have a value of 40 to account for. We ask, does 64 go into 40? No, it does not – so
we do not set the second bit. We then move right again and ask, does 32 go into 40?
Indeed it does, so we must set that bit.
Fantastic, we now have a value of 160 – however we need 168. You know the drill by now.
Subtract 160 from 168 and observe that we still need to account for a value of 8. Does 16
go into 8? No it does not, so we do not set the 4th bit. Move right again, does 8 go into 8?
In fact, yes. Let’s set that bit.
Our second decimal value of 168 is now converted to binary in the form of
Success!
10101000.
Ok, so far we have converted both 192 and 168 to binary. Here is where we are so far:
192.168 = 1100000010101000. Our third octet of the IP address is 10. The same process
applies. We start with the most significant bit, and try to get it to fit into the value we want.
In this case we have a decimal 10. We know that 128, 64, 32, and 16 do not fit into 10 – so
none of those bits need to get set. We arrive at bit 5 and notice that 8 does go into 10, so
let’s set that bit.
Nice work, but now we subtract 8 from 10 and realize we still need to account for a value
of 2. Move one space to the right and ask, does 4 go into 2? No it does not, so don’t set
that bit. Move again, does 2 go into 2? Yes it does, so let’s set that bit.
Success!We now know that decimal 10 is 00001010 in binary. Now we are up to:
192.168.10 = 110000001010100000001010. We only have one more byte to account for
and guess what. Today is your lucky day since the last byte is the same decimal value as
the one we just converted, 10. Now all we need to do is add these final 8 bits of 00001010
to what we have converted so far and we arrive at
11000000101010000000101000001010. So great job! You just manually converted the
decimal IP address of 192.168.10.10 to it’s binary representation of
11000000101010000000101000001010!
The Binary IP ANDED to the Binary Mask gives you all the answers.
You may be wondering why we just went through all that work to get our IP address into
binary. The reason is so that we can take the binary IP and the binary mask, and AND
them together. What does AND mean you say? Consider this AND truth table.
All it means to AND two binary numbers together is two compare their bit values at each
position to arrive at a final value. In the diagram above we are anding together the top row
and the middle row. The last row is the final anded value. So 0 and 0 = 0, 0 and 1 = 0, 1
and 0 = 0, and finally 1 and 1 = 1.
The top row is the binary equivalent of 192.168.10.10 and the middle row is the equivalent
of 255.255.255.0. The last row contains the result of anding them together. Great! That last
row is the Network Address that 192.168.10.10 is a part of. We’ll need to convert it from
binary to decimal to make it easier for us to read. So far we have been calculating from
decimal to binary, but going from binary to decimal is pretty straight forward. All we need to
do is break up the 32 bit binary address into groups of 8 and add up the value of each bit
that is set.
Sweet! Our Network is 192.168.10.0, and our First Available Host is 192.168.10.1.
Vue JS Directives
Let’s take a closer look at directives in this VueJS directives tutorial. Directives
are the part part of Vue that attach special meaning and behavior to plain html
elements on the page. The directive is like a token which indicates to Vue that it
has special control and access to this particular DOM element. Directives are
also a part of other view layer front end frameworks, however most web
developers have found the concept of directives easier to work with in Vue than
say Angular. Directives are really one of the foundations of understanding Vue,
so let’s look closer at them now.
<head>
<title>v-model</title>
<link rel="stylesheet" href="4.0.0-alpha.5.bootstrap-flex.min.css">
</head>
<body class="container">
<div id="app1">
<h2>{{ message }}</h2>
<input v-model="message" class="form-control">
</div>
<script src="vue.js"></script>
<script>
new Vue({
el: '#app1',
data: {
message: 'It\'s just that easy'
}
})
</script>
</body>
</html>
<head>
<title>v-show</title>
<link rel="stylesheet" href="4.0.0-alpha.5.bootstrap-flex.min.css">
</head>
<body class="container">
<div id="app1">
<h2>Enter text to send a message</h2>
<textarea v-model="message" class="form-control"></textarea>
<br>
<button v-show="message" class="btn">Send Message</button>
</div>
<script src="vue.js"></script>
<script>
new Vue({
el: '#app1',
data: {
message: ''
}
})
</script>
</body>
</html>
v-show Summary: When an element in the page has a v-show directive, it means that
entire element can be conditionally displayed based on the truthiness of the data property
it is bound to in Vue. If the data property is truthy, the element is displayed. If the data
property is falsy, the element is not displayed.
An element with v-show will always be rendered and remain in the DOM as v-show just
note:
toggles the display CSS property of the element.
Using v-if and v-else together in Vue
v-if is a little more powerful so to speak than v-show. Whereas v-show only toggles css to
change visibility, v-if will render or not render an element in the dom based on the
condition being tested. Here, we will make use of a v-if and v-else together, so that we
can change the message being presented to the user based on what they have typed in
the text area.
<head>
<title>v-if</title>
<link rel="stylesheet" href="4.0.0-alpha.5.bootstrap-flex.min.css">
</head>
<body class="container">
<div id="app1">
<h2 v-if="!message" class="text-info">Enter text to send a message</h2>
<h2 v-else class="text-success">Click "Send Message" to send</h2>
<textarea v-model="message" class="form-control"></textarea>
<br>
<button v-show="message" class="btn">Send Message</button>
</div>
<script src="vue.js"></script>
<script>
new Vue({
el: '#app1',
data: {
message: ''
}
})
</script>
</body>
</html>
This makes pretty good sense, right? If there is no message – tell the user to enter some
text, else, message must have some text – so tell them to click the button to send. So we
use v-if and v-else to determine which <h2> element to display, and v-show to toggle the
display of our button. Very cool!
<head>
<title>v-else-if</title>
<link rel="stylesheet" href="4.0.0-alpha.5.bootstrap-flex.min.css">
</head>
<body class="container">
<div id="app1">
<h3 v-if="message == 'one'" class="text-info">You typed 'one' <small>- now try 'two' or
'three'</small></h3>
<h3 v-else-if="message == 'two'" class="text-warning">You typed 'two' <small>- now try 'one' or
'three'</small></h3>
<h3 v-else-if="message == 'three'" class="text-danger">You typed 'three' <small>- now try 'one'
or 'two'</small></h3>
<h3 v-else>Type 'one', 'two', or 'three'</h3>
<textarea v-model="message" class="form-control"></textarea>
</div>
<script src="vue.js"></script>
<script>
new Vue({
el: '#app1',
data: {
message: ''
}
})
</script>
</body>
</html>
<head>
<title>template-v-if</title>
<link rel="stylesheet" href="4.0.0-alpha.5.bootstrap-flex.min.css">
</head>
<body class="container">
<div id="app1">
<textarea v-model="message" class="form-control"></textarea>
<br>
<template v-if="!message">
<h2>Enter text to send a message</h2>
<p>1. Place cursor in text area</p>
<p>2. Start typing</p>
</template>
<button v-show="message" class="btn">Send Message</button>
</div>
<script src="vue.js"></script>
<script>
new Vue({
el: '#app1',
data: {
message: ''
}
})
</script>
</body>
</html>
In this example we wrap the elements we want to render or remove from the DOM with
a <template> element, which has a v-if directive. Now, the v-if behavior affects all
wrapped elements inside the template. This can be very handy.
<head>
<link rel="stylesheet" href="4.0.0-alpha.5.bootstrap-flex.min.css">
<title>v-for</title>
</head>
<body class="container">
<div id="app1">
<h2>Example of range v-for</h2>
<ul class="list-group">
<li v-for="num in 5" class="list-group-item">
{{ num }} times 5 equals {{ num * 5 }}.
</li>
</ul>
</div>
<script src="vue.js"></script>
<script type="text/javascript">
new Vue({
el: '#app1'
})
</script>
</body>
</html>
<head>
<link rel="stylesheet" href="4.0.0-alpha.5.bootstrap-flex.min.css">
<title>v-for</title>
</head>
<body class="container">
<div id="app1">
<table class="table table-hover">
<thead class="thead-inverse">
<tr>
<th>Example of range v-for</th>
</tr>
</thead>
<tr v-for="num in 5">
<td>{{ num }} times 5 equals {{ num * 5 }}.</td>
</tr>
</table>
</div>
<script src="vue.js"></script>
<script type="text/javascript">
new Vue({
el: '#app1'
})
</script>
</body>
</html>
<head>
<title>v-for over an array</title>
<link rel="stylesheet" href="4.0.0-alpha.5.bootstrap-flex.min.css">
</head>
<body class="container">
<div id="app1">
<h2>Name some songs!</h2>
<ul class="list-group">
<li v-for="song in songs" class="list-group-item">
{{ song }}
</li>
</ul>
</div>
<script src="vue.js"></script>
<script type="text/javascript">
new Vue({
el: '#app1',
data: {
songs: [
"I Love It",
"Gangnam Style",
"Hotline Bling"
]
}
})
</script>
</body>
</html>
<head>
<title>v-for over an Object</title>
<link rel="stylesheet" href="4.0.0-alpha.5.bootstrap-flex.min.css">
</head>
<body class="container">
<div id="app1">
<h2>One great car</h2>
<ul class="list-group">
<li v-for="(value, property) in car" class="list-group-item">
The value of the <b>{{ property }}</b> property is <b>{{ value }}</b>
</li>
</ul>
</div>
</body>
<script type="text/javascript" src="vue.js"></script>
<script type="text/javascript">
new Vue({
el: '#app1',
data: {
car: {
make: "Tesla",
model: 'Model S',
color: 'Gray'
}
}
})
</script>
</html>
<head>
<title>vue js directive params</title>
<link rel="stylesheet" href="4.0.0-alpha.5.bootstrap-flex.min.css">
</head>
<body class="container">
<div id="app1">
<h2>Some great songs!</h2>
<ul class="list-group">
<li v-for="(song, index) in songs" class="list-group-item">
{{ index + 1}}. {{ song.artist }} sings "{{ song.name }}"
</li>
</ul>
</div>
<script src="vue.js"></script>
<script type="text/javascript">
new Vue({
el: '#app1',
data: {
songs: [
{
name: "I Love It",
artist: "Icona Pop"
},
{
name: "Gangnam Style",
artist: "PSY"
},
{
name: "Hotline Bling",
artist: "Drake"
},
{
name: "The Marriage of Figaro",
artist: "Mozart"
},
]
}
})
</script>
</body>
</html>
Note that since we used the index in the v-for loop, we are able to access the current
iteration as the list renders out. Since it is 0 based, we simply used index + 1 to make our
numbers start from 1.
• <button v-on:click=”doSomething”></button>
<head>
<title>v-on:click</title>
<link rel="stylesheet" href="4.0.0-alpha.5.bootstrap-flex.min.css">
</head>
<body class="container">
<div id="app1">
<button class="btn btn-info" v-on:click="addOne">Clicked {{count}} times.</button>
<button class="btn btn-warning" v-on:click="resetCount">Reset Count</button>
</div>
methods: {
addOne: function () {
this.count++;
},
resetCount: function () {
this.count = 0;
}
}
})
</script>
</body>
</html>
Here we set up two event listeners, one for each button. When the user clicks the first
button, the addOne function in the methods object gets called. When the user clicks the
second button, the resetCount function gets called in the methods object. Very nice! You
can also use the shorthand version if you like. It does the same thing, but it is less typing,
and who doesn’t like less typing?! It looks like this:
• <button @click=”doSomething”></button>
In addition to v-on:click, the more commonly used v-on directives are v-on:keyup and v-
on:submit.
<body class="container">
<div id="app1">
<ul class="lead">
<li>Fill in two numbers</li>
<li>Choose operation</li>
<li>Click calculate</li>
</ul>
<form>
<h2><span class="text-info" v-text="num1"></span> {{operator}}
<span class="text-primary" v-text="num2"></span>
<span v-show="result">=</span>
<span class="text-success" v-text="result"></span>
</h2>
<input v-model.number="num1" @click="result = ''" class="form-control col-xs-6">
<select v-model="operator" @click="result = ''" class="form-control col-xs-6">
<option>+</option>
<option>-</option>
<option>*</option>
<option>/</option>
</select>
<input v-model.number="num2" @click="result = ''" class="form-control col-xs-6">
<button type="submit" @click.prevent="calculate" class="btn btn-primary col-xs-
6">Calculate</button>
</form>
</div>
<script type="text/javascript" src="vue.js"></script>
<script type="text/javascript">
new Vue({
el: '#app1',
data: {
num1: 10,
num2: 20,
result: 30,
operator: "+"
},
methods: {
calculate: function () {
switch (this.operator) {
case "+":
this.result = this.num1 + this.num2;
break;
case "-":
this.result = this.num1 - this.num2;
break;
case "*":
this.result = this.num1 * this.num2;
break;
case "/":
this.result = this.num1 / this.num2;
break;
}
}
}
});
</script>
</body>
</html>
This example makes some interesting uses of the various directives we have covered so
far in addition to some new ones. When the page first loads we have num1 set to 10,
num2 set to 20, the operator set to addition, and the result set to 30. Typically, you’ll set all
your default data values in the data object so that something displays on initial render.
Now, the first thing we notice is that if we click in one of the inputs to change a number or
change the operator, instantly the = sign and result disappear. This is due to the directive
of @click=”result = ”” that we have assigned to each input in the form which sets the
result variable to an empty string. Now, the = operator in our markup is inside of a v-
show like so <span v-show=”result”>=</span>. If the result variable is not truthy, then
we will not show the = operator. Additionally, we make use of the v-text directive in our
markup like so <span class=”text-success” v-text=”result”></span> which is the
equivalent of <span class=”text-success”>{{ result }}</span>. So the equals sign, and
the result of the operation are never displayed if the result variable is not truthy. You’ll also
note that each <input> uses a v-model.number directive, which means we expect an
actual number value – not a string from this input. The <select> tag also makes use of a v-
model and you can see how that translates into selecting which operation to use in the
example. Finally, we notice that the button makes use of a @click.prevent directive which
instructs the button to *not* submit the form on click. Fantastic!
<head>
<title>v-bind</title>
<link rel="stylesheet" href="4.0.0-alpha.5.bootstrap-flex.min.css">
</head>
<body class="container">
<div id="app1">
<card v-bind:carddata="{cardheader: 'https://google.com', cardtitle: 'Google', cardfooter:
'@google' }">
</card>
<card v-bind:carddata="{cardheader: 'https://vuejs.org', cardtitle: 'Vue', cardfooter: '@vuejs'
}">
</card>
<card v-bind:carddata="{cardheader: 'https://laravel.com', cardtitle: 'Laravel', cardfooter:
'@laravel' }">
</card>
</div>
<template id="card-template">
<div class="card">
<div class="card-header">
{{ carddata.cardheader }}
</div>
<div class="card-block">
<h4 class="card-title">{{ carddata.cardtitle }}</h4>
</div>
<div class="card-footer">
{{ carddata.cardfooter }}
</div>
</div>
</template>
new Vue({
el: '#app1'
})
</script>
</body>
</html>
This example is a really cool example of turning a Bootstrap Card into a component in
Vue. There is a fair amount happening in this example, but the main demonstration here is
how we are binding a custom data object to a Vue component so we can easily create our
own cards by simply putting a <card> tag on the page. With our component set up, we
display three different cards on the page, each having it’s own data within it thanks to the
unique data object bound to each card via the v-binddirective.
Vue JS Directives Summary
Wow! That was a pretty epic dive into using directives in VueJS. Remember, directives are
special attributes beginning with the v- prefix assigned to html in a Vue powered page to
give them special powers. As a quick recap, here are some of the directives we looked at,
and a super concise summary of each one.
• v-model
• v-show – used to conditionally display an element (css based)
• v-if – used to conditionally render an element
• v-else-if – serves as an “else if block” for v-if and can be chained multiple times
• v-else – displays an element when v-if evaluates to false
• v-for – iterate over a range, an array, an object, or an array of objects
• v-on – listen to various DOM events (click, keyup, submit, etc..)
• v-bind – used to dynamically bind one or more attributes, or a component prop, to an
expression
• v-text – same as {{ interpolation }} and updates the element’s textContent
ES6 let vs var vs const, oh my! ES6 is here, and developers are making use of
it now. There are a lot of differences between ES6 and it’s predecessor ES5,
and if you want to make use of the new features available to you, you need to
learn about how things work in ES6. In this tutorial, we’ll start out at the very
beginning in ES6 and examine the new let keyword, const keyword, as well as
block scope in ES6. Buckle up, and let’s dig into the beginnings of ES6 right
now!
// undefined
Here we have a simple script that logs out the value of a userid. Note that we are
assigning the value of the userid after we log it out. In this instance we find the result
of undefined. How can it even be undefined however? This is because of the way
JavaScript uses hoisting, which means it moves the declaration to the top of any function,
or in this example we are in the global scope. Let’s see how things might change if we use
the let keyword in ES6.
This time around we make use of the let keyword, and notice the difference. We get a
pretty gnarly error: ReferenceError: can’t access lexical declaration ‘userid’ before
initialization. Why does this happen? This is because in ES6, using the let keyword
removes the hoisting that usually takes place when a var is used instead. In modern
JavaScript we are finding many software developers abandoning var and moving
to let exclusively because it helps reduce hard to find errors and bugs.
// 1
Ah yes, finally. We get what we have wanted, which is to properly assign the number 1 to
our useridvariable. It does seem a bit odd that they called it a let, since a let is still a
variable, but alas this is the naming convention of the new variable type in ES6. Let it be,
let it be, speaking words of wisdom, let it be…
// undefined
Just like using var in ES5, if we declare but do not initialize a variable using let in ES6,
then the value is set to undefined.
// 10
This is an example making use of block scope in ES6. In this example here, we
define userid two times. First it is defined in the global scope, then we define it in between
the curly braces which denotes a block of code. When we log out the value of that variable
outside of the block, note that we get the value of 10. This is what is called block scope.
Changing those let keywords back to var gives us a very different result. Let’s see.
'use strict';
var userid = 10;
{
var userid = 200;
}
console.log(userid);
// 200
You can see that when we go back to using the var keyword, that assignment of 200
to userid inside the block basically overwrites the original variable declaration and
initialization of 10 to userid. Of course just having a random block like this example is not
really common, but this would apply to things like if and for statements which make use of
blocks.
Can you access a variable outside the block when let is used?
What happens if we try to access a variable defined with let outside of the block it was
used in? Let’s test it out now.
'use strict';
{
let userid = 200;
}
console.log(userid);
It looks like we get an error of ReferenceError: userid is not defined[Learn More]. The
friendly folks at the Mozilla Developer Network tell us exactly what this means: There is a
non-existent variable referenced somewhere. This variable needs to be declared, or you
need make sure it is available in your current script or scope. What that tells us in this
example is that when a block terminates, then any local variables defined in that block are
no longer available.
// 1234
We declare a function and assign the value of 1234 to the userid variable in that function.
Note useridhas not been officially declared yet. After the function, we declare userid and
set it to null using let. updateUserId() get’s called, then we log out the value of userid.
The result of this call to console.log is 1234. This is because the use of userid in the
function happens in the Temporal Dead Zone. The compiler makes note of userid in the
function even though it is not declared yet, and this is why it still works and logs out 1243.
ES6 Block Scope With For Loops
'use strict';
let userid = 321;
for (let userid = 0; userid < 10; userid++) {
console.log(userid);
}
console.log(userid);
// 0
// 1
// 2
// 3
// 4
// 5
// 6
// 7
// 8
// 9
// 321
In looking at the output from this example ES6 script, we can see that the userid variable
declared before the for loop using the let keyword, and the userid declared inside the for
loop, also with the let keyword, are two different variables that each have their own values
and own scope associated with them. As the for loop begins to run, it logs out the value
of userid on each iteration. In this part of the script, userid is scoped to the for loop. When
the loop finishes, that is the end of that block and outside of that block userid holds the
value 321, which was declared and initialized at the top.
// 5
Now, the function that lives at index 0 in the array is returning the value of i for the first
iteration of the loop. You would think then that i should be 0, but we see 5 instead. Why is
that? The reason is because a closure gets created over the i variable and at the end of
the loop, i is set to 5. Because of this, the function is always going to return 5.
'use strict';
let arrayOfFunctions = [];
for (let i = 0; i < 5; i++) {
arrayOfFunctions.push(function () {
return i;
});
}
console.log(arrayOfFunctions[0]());
// 0
In this second iteration of using closure, we change it up and use let instead of var in
the for loop. When we now log out the value of calling the function that exists at index 0 in
the array, the result is 0. This is a little more along the lines of what you might expect.
When we use let in a for loop, each iteration of the loop will get it’s own i variable. Any
closures created will close over it’s own value of iunlike when using var.
Constants in ES6
In ES6, you can now make use of constants in your JavaScript code by use of
the const keyword. A constant is used when you need to declare something to have a
value that will not change at any time. Let’s see a few examples of using a constant and
making use of const in ES6.
// Too High
Making use of all uppercase letters for the name of the constant is not actually required,
but this is a convention in programming across almost any language so it makes sense to
use it here in ES6 JavaScript as well.
When making use of the const keyword, you must initialize it at the same time. If you don’t,
you’ll run into a problem like the example above shows.
If you try to assign a new value to a constant after it has already been declared and
initialized, you will get an error along the lines of what you see here: TypeError: invalid
assignment to const `TAXES’. Once a constant is declared and initialized, that’s it, you
can’t update or change it’s value in that scope.
console.log(TAXES);
// Too High
In this example, we can see that the TAXES constant actually gets assigned a value twice.
No error is thrown, and we get a value of ‘Too High’ when we log out the value of TAXES.
Wat? Well, what happens is that similar to let, a const has the concept of block scope.
Therefore, when the script delves into the if branch, it does indeed assign ‘Way Too High’
to the TAXES constant. It just so happens however that this instance of TAXES is
completely separate from the TAXES constant defined at the beginning of the script. There
are two scopes in play here, the block scope of the if statement, and the outer global
scope. Constants of the same name can peacefully coexist in different scopes, even with
the same name. There are no problems with that.
Let’s take a look at ES6 arrow functions. If you’ve spent any amount of time
programming JavaScript, you know that after awhile, it feels like you’re typing
out that function keyword over and over and over. You write a function here,
you write a function there. Here a function, there a function, every where a
function function. That’s because anytime you want something to actually
happen in your script, you need to write another function! Have you ever
thought, “it might be nice if I didn’t have to write out the function keyword so
darn often”. If so, you’re in luck with ES6, because there is a new shorthand for
writing functions and they are referred to as ES6 Arrow Functions. Let’s
investigate them a little bit now.
Arrow Functions use Fat Arrow Syntax
You may have heard of these new arrow functions as using the fat arrow syntax. This is
because this new symbol for defining functions in ES6 is the combination of an equals
sign = and a greater than symbol >. Put them together and now you have your fat arrow =>.
The equals sign is what makes the arrow fat. So let’s start off by creating a function in
ES5, and then see what we have to do in order to turn it into an ES6 Arrow Function.
console.log(sum(7, 12));
// 19
We can rewrite this function using fat arrows => in a couple of steps.
console.log(sum(7, 12));
// 19
Congratulations! You have just created your very first arrow function in ES6! Let’s take it a
step further.
You can omit the return keyword for simple expressions by placing everything on one
line and removing the brackets or curly braces like so.
var sum = (num1, num2) => num1 + num2;
console.log(sum(7, 12));
// 19
Finally, if there is only one argument for the function, you can even leave off the
parenthesis like so.
var square = num1 => num1 * num1;
console.log(square(7));
// 49
You now have less chance of developing carpel tunnel syndrome from the repetitive stress
of typing function so much.
// function
// 100
If we log out the value of a call to the points() function, we can see we get the result
of 100. You see, the code is actually handling the return of the value for us, we do not need
to specify it manually by typing the return keyword.
// 40
The same function works the same way if we omit the parenthesis.
'use strict';
var points = multiplier => multiplier * 10;
console.log(points(4));
// 40
// 90
// 90
Single line arrow functions are perfect for simple expressions. More often than not, you are
going to need to make use of functions that do more than just a simple expression that can
fit on one line. In that case, you can certainly make use of brackets like you are so used to
doing when defining functions. One key thing to remember when using brackets with arrow
functions: You must include the returnkeyword to return a value from your function. The
return of a value will not happen automatically like it would with a single line arrow function.
Keep this in mind.
// #document
In ES5 whenever we have an event handler in our code, this gets set to the element that
receives the event. This results in not having access to the context of the function.
Let’s now change this code up to make use of an arrow function, and see how this
impacts this.
'use strict';
document.addEventListener('click', () => console.log(this));
// Window {...}
This time around, since we are using an arrow function, this gets set to the global Window
object since we are in the global scope. We are not in the context of a function. With the
arrow function, this refers to the actual context of the code we are running.
Taking this idea a bit further, let’s look at calling functions that exist in objects in ES5 vs
ES6.
'use strict';
var bill = {
servicenumber: 557,
process: function () {
console.log(this);
}
};
bill.process();
This shows that in this example, this is getting set to the object on which the function is
called.
What happens if we change this to use an arrow function. Let’s see.
'use strict';
var bill = {
servicenumber: 557,
process: () => console.log(this)
};
bill.process();
// Window {...}
With the arrow function in place, we get the context of the code we are running. Or in other
words, what scope is this particular code operating in? In this case it is the global scope,
therefore we get the global Window object since this is what represents the global scope.
// 557
This example is an object literal which has a servicenumber value, and a process function.
That process function, actually returns a function. Then we call the process function, and
immediately call the returned function. This is what is meant by bill.process()(); So what is
happening with this inside the returned function? Well, the arrow function is
executing within the context of another function, and this is why we see the value
of this.servicenumber rather than the global Window object.
// 557
Now check that out! You would think that the servicenumber would be 900, since we tried
to bind the newBill object literal to our process function. This does not work however with
ES6 arrow functions. This did not produce any errors or anything, so if you did not know
any better, you would have no clue why bind() was failing. With ES6 Arrow Functions, you
can not use bind().
Just like the example above, making use of call() also does not work!
'use strict';
var bill = {
servicenumber: 557,
process: function () {
return () => console.log(this.servicenumber);
}
};
var newBill = {
servicenumber: 900
};
bill.process().call(newBill);
// 557
With ES6 arrow functions, using bind(), call(), and apply(), are all useless! You can not
change the value of this.
You’ll need to keep the fat arrow on the same line, and you’ll be ok.
'use strict';
var somenumber = () => 1234;
console.log(typeof somenumber);
// function
// false
Let’s look at some examples of using the new class syntax in ES6. These first two
examples make use of this, but it is not in the context of an arrow function. This is just to
get ourselves familiar with the syntax before testing out this within an arrow function in
more complex code.
log() {
this.games.forEach(function (game) {
console.log(game.name + ' on ' + game.platform);
})
}
}
class Game {
constructor(name, platform) {
this.name = name;
this.platform = platform;
}
}
new GamesCollection([
new Game('Zelda', 'Nintendo'),
new Game('Halo', 'Xbox'),
new Game('Mario', 'Nintendo')
]).log();
// Zelda on Nintendo
// Halo on Xbox
// Mario on Nintendo
Using an arrow function in the log function
class GamesCollection {
constructor(games = []) {
this.games = games;
}
log() {
this.games.forEach((game) => {
console.log(game.name + ' on ' + game.platform);
})
}
}
class Game {
constructor(name, platform) {
this.name = name;
this.platform = platform;
}
}
new GamesCollection([
new Game('Zelda', 'Nintendo'),
new Game('Halo', 'Xbox'),
new Game('Mario', 'Nintendo')
]).log();
// Zelda on Nintendo
// Halo on Xbox
// Mario on Nintendo
In both of the above examples, we get the same result whether we are using ES5
functions of ES6 arrow functions in the log function. Each type does not make use of
the this keyword, so that is to be expected.
Let’s now change things up to make use of the this keyword within the log function to see
what happens.
class GamesCollection {
constructor(games = []) {
this.games = games;
}
log() {
this.games.forEach(function (game) {
console.log(this);
})
}
}
class Game {
constructor(name, platform) {
this.name = name;
this.platform = platform;
}
}
new GamesCollection([
new Game('Zelda', 'Nintendo'),
new Game('Halo', 'Xbox'),
new Game('Mario', 'Nintendo')
]).log();
// undefined
// undefined
// undefined
log() {
this.games.forEach((game) => {
console.log(this);
})
}
}
class Game {
constructor(name, platform) {
this.name = name;
this.platform = platform;
}
}
new GamesCollection([
new Game('Zelda', 'Nintendo'),
new Game('Halo', 'Xbox'),
new Game('Mario', 'Nintendo')
]).log();
In this example above, this refers to each instance of the GamesCollection Object as you
iterate through them.
Testing this against different instances of an object
Let’s look at one more example of how this is bound in arrow functions vs ES5 functions.
Below, we set up a constructor for a Language. We then extend the prototype of Language
with a greet() function. This function simply logs out it’s name after a short delay.
var Language = function (name, delay) {
this.name = name;
this.delay = delay;
};
Language.prototype.greet = function () {
setTimeout(() => {
console.log('Hi, I am ' + this.name);
}, this.delay);
};
java.greet();
cpp.greet();
// Hi, I am JavaScript
// 2 seconds later
// Hi, I am PHP
Nice! In this first example, we are using an arrow function and when we call the greet
function on two different objects, this automatically points to the correct instance.
Let us now remove the arrow function and replace it with an ES5 style function. We get
different results.
var Language = function (name, delay) {
this.name = name;
this.delay = delay;
};
Language.prototype.greet = function () {
setTimeout(function() {
console.log('Hi, I am ' + this.name);
}, this.delay);
};
java.greet();
cpp.greet();
// Hi, I am
// 2 seconds later
// Hi, I am
Now, the code breaks because this now points to the global Window object, rather than
any instance of Language.
To fix this issue in ES5, we had to make use of bind() like so
var Language = function (name, delay) {
this.name = name;
this.delay = delay;
};
Language.prototype.greet = function () {
setTimeout(function () {
console.log('Hi, I am ' + this.name);
}.bind(this), this.delay);
};
java.greet();
cpp.greet();
// Hi, I am JavaScript
// 2 seconds later
// Hi, I am PHP
The code now works again when using ES5 functions and bind().
// 500
Here we declare a function with two parameters, carId with a default value of 500 –
and make with a default value of Tesla. In the function, we just log out the two parameters
separated by a comma. When we call the function, notice we pass undefined as the first
argument and the string ‘Honda’ as the second argument. When we execute the function,
we see 500, Honda. Since we pass in undefined as the first argument, JavaScript will look
for the default value and use that. By passing in ‘Honda’ as the second argument,
JavaScript overwrites the default value provided in the function declaration and logs
out Honda instead of Tesla.
'use strict';
let getCar = function (carId = 500, make = 'Tesla') {
console.log(carId + ', ' + make);
};
getCar(undefined, 'Honda');
// 500, Honda
This next example shows how to set up a blue light special discount, making use of a
default value for the second parameter of discount. When we run the function we pass in
1000 as the first argument for the price parameter. Since our discount parameter has a
default value of 20%, we get the value of 800 which is a 20% discount off of 1000.
'use strict';
function blueLightSpecial(price, discount = .20) {
return price - (price * discount);
}
console.log(blueLightSpecial(1000));
// 800
We can also refactor the blue light special to make use of a function call within the default
function parameter list like so.
'use strict';
function getDiscount() {
return .20;
}
console.log(blueLightSpecial(1000));
// 800
// 107000
This is an interesting example where we have two parameters of price and tax. What’s
interesting is that the second parameter takes the result of an expression as it’s default
value. The expression makes use of both the first parameter, and an external variable
of salesTax. Running the function shows us we get the price we expect, and we find that
using expressions as default parameters is very flexible.
'use strict';
let salesTax = 0.07;
let getCarCost = function (price, tax = price * salesTax) {
console.log(price + tax);
};
getCarCost(100000);
// 107000
This fun example shows us making use of a callback as the first parameter and a delay of
2000 milliseconds as the second parameter. All we do is make use of the JavaScript
setTimeout function to run a callback after a specified amount of time. We then call the
function, and note we actually pass in an arrow function to the twoSecondDelay() function
as the first argument. We do not provide the second argument, but that assumes a default
value of 2000 since we used that in the function declaration. When we run the function,
after a two second delay we see the text, finished.
'use strict'
function twoSecondDelay(callback, delay = 2000) {
setTimeout(callback, delay);
}
// 107000
Here is an example passing in four parameters, with only the first being required. All others
are assigned a default value.
'use strict'
function addReminder(meeting, date = new Date().getTime(), length = 60, timeout = 1000) {
let reminder = {
meeting: meeting,
date: date,
length: length,
timeout: timeout
};
console.log(reminder);
}
addReminder('Interview Candidate');
// Object { meeting: "Interview Candidate", date: 1485876881851, length: 60, timeout: 1000 }
Arguments.length Considerations
Let’s examine what happens to the arguments array within a function when using default
function parameters. Notice that the use of default parameters has no bearing on the
length of the arguments list inside the function. When we call getCarCost(), we only
specify one argument of 100000. Notice the function declaration makes use of two default
parameters. It turns out this has no impact on arguments.length.
'use strict';
let getCarCost = function (price, tax = price * 0.07) {
console.log(arguments.length);
};
getCarCost(100000);
// 1
To examine this concept just a bit further, we have this example right here that looks at the
length and values of the indices that exist in arguments. We have a
function listArguments() that logs out the length of arguments, checks to see if the first
parameter is equal to the first value in arguments, and also checks to see if the second
parameter is equal to the second value in arguments. Note when the code runs that
arguments.length is only 1. The make parameter is equal to the value held in arguments[0]
which is Tesla Model S. Finally, we see that price does not equal arguments[1]. This is
because even though price exists as a default function parameter, it was not provided as
an argument to listArguments() when the function was called. If nothing else, this cements
our understanding of parameters vs arguments in JavaScript.
'use strict';
function listArguments(make, price = 100000) {
console.log(arguments.length);
console.log(make === arguments[0]);
console.log(price === arguments[1]);
};
// 1
// true
// false
This section of our series on ES6 features looks at the new Rest and Spread
Operators. An almost constant requirement in programming is the ability to
easily take a group of values, and put them into an array. Additionally, it is also
quite common to need to take values in an array, and extract each value to it’s
own entity so to speak. The new Rest and Spread operators do just that for us
when writing JavaScript in ES6. Let’s take a look at making use of ES6 Rest
and Spread operators here.
Introducing the REST Parameter in ES6
The rest parameter is this sequence of three dots ... used in a function declaration to
specify that there may be several remaining arguments, but we will gather them all up and
place them into an array. In other words, the rest of the arguments will be collected with
the rest parameter. Rest refers to gathering up several parameters, and putting them all
into a single array. To summarize: In ES6, the final argument of a function declaration can
be preceded by .... This collects all the remaining arguments when the function is called,
into an array. They call it a rest parameter, because it gets the rest of the parameters
passed to a function.
Let’s declare a function called displayTags(), and note that we are passing postId as an
argument and ...tags as an argument. The three dots that precede tags is the rest
symbol. It will gather up all of the remaining parameters to the function. Inside the function,
we just log out tags instanceof Array. Finally we simply call displayTags() while passing
in 4 parameters as you see. We get the output of true, since tags will be set to an array.
'use strict';
let displayTags = function (postId, ...tags) {
console.log(tags instanceof Array);
};
displayTags(25, 'php', 'javascript', 'laravel');
// true
Taking this same example, we will not log out tags which we know is an array. We see the
output of [ “php”, “javascript”, “laravel” ]. It is clear to see that ...tags gathered up all of the
parameters other than the first argument which was postId.
'use strict';
let displayTags = function (postId, ...tags) {
console.log(tags);
};
displayTags(25, 'php', 'javascript', 'laravel');
Let us now run the same code, but this time around we will only pass one value when we
call the function. We will pass the postId only, but still log out the tags variable. We still get
an empty array for ...tags. Even though there are no additional parameters to gather
up, tags still gets set to an empty array.
'use strict';
let displayTags = function (postId, ...tags) {
console.log(tags);
};
displayTags(25);
// Array [ ]
Length of a function using rest
In this example of the displayTags() function, we will declare it again with postId in the
first argument position, and ...tags in the second argument position. Upon running the
code, we find the length of the function to be 1. This means that when you access the
length of a function, the rest parameter is ignored. The output of 1 is referring
to postId here.
'use strict';
let displayTags = function (postId, ...tags) {
};
console.log(displayTags.length);
// 1
// 4
function sum(...numbers) {
return numbers.reduce((previous, current) => previous + current);
}
console.log(sum(1, 1));
console.log(sum(4, 4, 4));
console.log(sum(5, 10, 15, 100));
// 2
// 12
// 130
Let’s look at one more example of a rest parameter. Here we can see the argument list is a
rest parameter placed in parentheses since it is an arrow function. We need to do this
as ...args is implying multiple arguments. Since the rest parameter must be the last
argument of a function, there can only be one rest parameter in a function. If the rest
parameter is not last, your script will throw an error.
'use strict';
((...args) => {
console.log(args);
})('First', 'Second', 'Third');
// 22
// 9
Let’s make use of actual word characters in this example. We apply the spread operator to
‘Boo Yeah!’ and surround it with brackets. What this says is, break apart each single value
in the string, then immediately place each individual value into an array. When we run the
code, that is exactly what we get as you can see here.
'use strict';
// Array [ "B", "o", "o", " ", "Y", "e", "a", "h", "!" ]
Like we mentioned, the spread operator has no rules as to where you can use it like the
rest parameter. The rest parameter must be last, but this is not the case for the spread
operator. Check out this example where we apply the spread operator to the string
argument of ‘Foo’ in the second position. When we run the code we can see ‘Boo’ stays
intact, ‘Foo’ gets spread out like we would expect, and ‘Too’ is left in tact.
'use strict';
// 3
[, , , ...result] = reallycool;
console.log(result);
Object Literals in ES6 have seen some improvements over their ES5
predecessors. These improvements help developers to solve problems with
less typing and less code. In addition to this, many find the new syntax styles to
be more concise and easier to understand. In this ES6 tutorial, we’ll take a look
at Object Enhancements such as Object Literal Shorthand, Object Method
Shorthand, Computed Object Keys, and Object Destructuring. Let’s jump
right in.
var legoset = {
partnumber: partnumber,
description: description
};
console.log(legoset);
let legoset = {
partnumber,
description
};
console.log(legoset);
function getMotorcycle() {
var make = 'Alta';
var model = 'Redshift MX';
return { make: make, model: model };
}
console.log(getMotorcycle().make);
console.log(getMotorcycle().model);
// Alta
// Redshift MX
function getMotorcycle() {
let make = 'Alta';
let model = 'Redshift MX';
console.log(getMotorcycle().make);
console.log(getMotorcycle().model);
// Alta
// Redshift MX
var legoset = {
partnumber: partnumber,
description: description,
buildset: function buildset() {
return 'Building set number ' + this.partnumber + ', ' + this.description;
}
};
console.log(legoset.buildset());
let legoset = {
partnumber,
description,
buildset() {
return 'Building set number ' + this.partnumber +
', ' + this.description;
}
};
console.log(legoset.buildset());
function getMotorcycle() {
var make = 'Alta';
var model = 'Redshift MX';
return {
make: make,
model: model,
race: function race() {
return 'Racing an ' + this.make + ' ' + this.model;
}
};
}
console.log(getMotorcycle().race());
// Racing an Alta Redshift MX
function getMotorcycle() {
let make = 'Alta';
let model = 'Redshift MX';
return {
make,
model,
race() {
return `Racing an ${this.make} ${this.model}`
}
};
}
console.log(getMotorcycle().race());
Here is the ES5 code required to do the same thing. Not fun.
'use strict';
let legoset = {
[description.toLowerCase()]: partnumber
};
console.log(legoset);
This is a bit of a mind bender right here where we set up an array, and then use that array
in different ways as the actual keys of our coolobject. By placing brackets around the key
of an object, you are setting up a computed key in ES6.
'use strict';
let coolobject = {
funarray,
[funarray]: 'the value held in "5,10,15"',
[funarray.length]: 'object key is 3',
[{}]: 'empty object'
};
console.log(coolobject);
// Object { 3: "object key is 3", funarray: Array[3], 5,10,15: "the value held in "5,10,15"", [object
Object]: "empty object" }
console.log(coolobject.funarray);
console.log(coolobject['funarray']);
console.log(coolobject[funarray]);
console.log(coolobject[funarray.length]);
console.log(coolobject['[object Object]']);
console.log(coolobject[coolobject]);
// Array [ 5, 10, 15 ]
// Array [ 5, 10, 15 ]
// the value held in "5,10,15"
// object key is 3
// empty object
// empty object
ES6 Object Destructuring
Taking data out of objects and arrays for use in your program is one of the most common
things you’ll need to do when writing JavaScript. ES6 adds some new features to try and
make this easier with destructuring. When using a destructuring expression, you take the
value on the right of the = sign, and break it apart to assign variables on the left of
the = sign. Hopefully it makes sense in this example here.
Object Destructuring Example 1
As we can see here, by simply using an assignment operator we can take the values of an
object and extract them into new variables to use in your program. In addition, you can
pick and choose the values you want to work with, it doesn’t need to be the whole object.
So here we have our student object, but we only want to make use of the email and
nextClass keys in our code. By using the expression of let {email, nextClass} = student;,
that is exactly what we accomplish.
'use strict';
let student = {
name : 'Jeff',
email : 'jeff@outlook.com',
classesCompleted : [ 'English', 'Math' ],
nextClass : 'Programming'
};
let { email, nextClass } = student;
let purchaseprice = {
sale: '5',
average: '10',
markup: '15'
};
let {sale, average, markup} = purchaseprice;
console.log(markup);
// 15
It’s important to make sure that the properties match up between the object and our new
variables. So in our purchaseprice object here we have a sale, average,
and markup property. Those match exactly to our new variables that we are using
destructuring with.
Destructuring Example 3
'use strict';
let purchaseprice = {
sale: '5',
average: '10',
markup: '15'
};
let {sale: newSale, average: newAverage, markup: newMarkup} = purchaseprice;
console.log(newMarkup);
// 15
Example 3 uses the same object literal as we had in example 2, however we are using a
new syntax for destructuring. In the prior examples, we have assumed that our new
variables and the keys of the object being destructured are exactly the same. In fact they
need to be in order for this to work properly. What about if you want to use new variable
names as you destructure? This is also possible and it is exactly what we did here in
example 3.
Destructuring Example 4
This is another simple example of object destructuring which makes use of simple string
values in the object literal. We then destructure the company object into the variables
of name and industry. Logging out those values shows the correct result.
'use strict';
let company = {
name: 'Microsoft',
industry: 'Software'
};
console.log(name);
console.log(industry);
// Microsoft
// Software
Destructuring Example 5
Again we make use of the company object but add a few keys to the object. The
new products key holds an array of values, and the ticker key holds a simple string value.
When we destructure we choose to only make use of products and ticker, and this is
perfectly fine. You do not need to make use of every single key when destructuring. You
can pick and choose what you need for your application.
'use strict';
let company = {
name: 'Microsoft',
industry: 'Software',
products: ['OS', 'Applications'],
ticker: 'MSFT'
};
console.log(products);
console.log(ticker);
Destructuring Example 6
This is a pretty cool new feature here where you can use object destructuring as a function
argument. Notice how in the function declaration, we can simply pass in an object
destructuring expression and we immediately get access to all the values of the object
inside the function.
'use strict';
// Microsoft
// Software
// Array [ "OS", "Applications" ]
// MSFT
Destructuring Example 7
Let’s look at one final example to understand how object destructuring works. All we have
is a simple function that says hello to someone, and mentions their job. We call the
function, passing in an object and it works great.
'use strict';
Let’s now jump into learning about ES6 modules. For this lesson, we are going
to be making use of a fantastic piece of software for modern JavaScript
development. Traceur.js by Google is a JavaScript compiler that is super easy
to use, and is great if you don’t want to be bogged down by a massive build
system. All you have to do is include Traceur in your page, and you’re good to
go. It also allows for ES module loading. The goal of this tutorial is to be able to
fully explore the features of ES6 modules, without having to worry about getting
excessive tooling configured and set up. Let’s dig in to ES6 modules now!
ES6 Module Playground
To get started, we need a simple HTML file set up for us which includes the Traceur.js
JavaScript files we need so we can quickly start testing out our modules. This is the base
HTML file we will use for the duration of these exercises.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>ES6 Modules</title>
<body>
</body>
</html>
The source for these JavaScript files to include in your HTML can be found at
the Traceur.js github page. You can download them manually, or use NPM or YARN to
install the package for you. For this tutorial, we used the command of yarn add traceur,
then grabbed the files we needed from there. The base.jsfile is simply our own JavaScript
file that is the main entry point of modules into our pages. We no longer have to declare
multiple script tags to include various JavaScript files when using module loading.
Traceur Overview
So what are these extra files that we are including in our test page? These files come from
the Traceur package. Traceur is a compiler / transpiler which allows you to make use of all
the future JavaScript features that are not currently a native offering in modern web
browsers. In addition to making all features of ES6 available to you, Traceur also supports
some ES.next experimental features. If you are familiar with how BabelJS works, Traceur
shares many of the same features. You can also try out Traceur online to see how it
compiles down your ES6 code.
Using System.import
For our first example, we will simply demonstrate how the System.import(); syntax works.
We use System.import(‘./base.js’); to import the base.js module. Let’s see it in action.
base.js
console.log('Running from the base.js file');
index.html
What this shows is that as soon as you load a module, or file, using an ES6 module loader
– any code contained in that module is immediately executed. A module is executed only
one time, the first time it is loaded. Let’s try a few more things.
Testing variable assignment in Modules
base.js
let emulator = 'Dolphin';
index.html
console.log(emulator);
emulatormodule.js
export let emulator = 'Dolphin';
index.html
emulatormodule.js
export let emulator = 'Dolphin';
export let game = 'Sonic Unleashed';
index.html
emulatormodule.js
export let emulator = 'Dolphin';
export let game = 'Sonic Unleashed';
index.html
console.log(randomvalue);
emulatormodule.js
export let emulator = 'Dolphin';
let game = 'Sonic Unleashed';
console.log(
`Playing ${values.game}
on ${values.emulator} emulator
using ${values.controller} controller`
);
emulatormodule.js
export let emulator = 'Dolphin';
export let game = 'Sonic Unleashed';
export let controller = 'Xbox One';
index.html
console.log(
`Playing ${values.game}
on ${values.emulator} emulator
using ${values.controller} controller`
);
console.log(
`Playing ${values.game}
on ${values.emulator} emulator
using ${values.controller} controller`
);
emulatormodule.js
export let values = {
emulator: 'Dolphin',
game: 'Sonic Unleashed',
controller: 'Xbox One'
};
index.html
Exporting a Function
We can also export a function from one module to another. Here we set up
a playGame() function in the emulatormodule.js module and export it to
the base.js module.
base.js
import {emulator, playGame } from 'emulatormodule.js';
playGame();
emulatormodule.js
export let emulator = { version: 'Dolphin'};
index.html
Exporting multiple Functions
If you need to export more than one function, go right ahead. We’ll export two functions
here and see the result.
base.js
import { playGame, changeGame } from 'emulatormodule.js';
playGame();
changeGame();
emulatormodule.js
export function playGame() {
console.log('Playing Super Mario');
}
library.log();
Games.js
export class Games {
constructor(games = []) {
this.games = games;
}
log() {
console.log(this.games);
}
}
<meta charset="UTF-8">
<title>ES6 Modules</title>
<link rel="stylesheet" href="bootstrap.min.css">
listgames() {
var element = document.querySelector('#games');
for (let game of this.games) {
game = '<li class="list-group-item">${game}</li>';
element.insertAdjacentHTML('beforeend', game);
}
}
}
library.listgames();
</script>
</head>
<body class="container">
</body>
</html>
ES6 Modules With Traceur.js Summary
This concludes our exploration of ES6 modules while using Traceur.js. It turns out, there
are many other ways to handle working with modules such as Babel, Webpack, Rollup,
Browserify, etc, etc. In some ways it almost feels like the days when we had jQuery, Moo
Tools, Scriptaculous, and others vying for the position of the defacto dom manipulation
library. We are now seeing how ES6 tooling will evolve. Over time, it is likely these tools
will consolidate and a clear leader will emerge with a somewhat standardized way of doing
things. Until then, we are all experimenting as the JavaScript ecosystem moves into the
future.
During this tutorial we covered setting up a basic ES6 sandbox for testing our module
loading and went over a high level overview of Traceur and how you can use it. We then
took a look at how to load modules as files, leveraging the power of the System.import();
syntax in our main HTML file. From there we tested a variety of exports and imports
between ES6 modules including variables, functions, and classes. Finally we wrapped it
out with an example of making use of the <script type=”module”> syntax to embed an ES6
module right on our page.
• 1Define a Class
• 2Instantiate an Object
• 3Create a Method
• 4Prototype Considerations
• 5Constructor Functions
• 6Assign class to variable
• 7Inheritance, Extends, and Super
• 8Method Overrides
• 9Super in a method
• 10Properties on Class Instances
• 11Static Methods
• 12Getters and Setters
• 13Classes as First Class Citezens
}
console.log(typeof Vehicle);
// function
Creating a class is super easy. All you do is use the class keyword followed by a name for
the class, and then your opening and closing curly braces. Pretty simple stuff. After we
create our class here, we actually log out the typeof Vehicle of our class. Wait a minute, it
says it’s a function. Why isn’t it a class? Well, this shows that in fact using
the class keyword does not really give you access to an actual class type in JavaScript.
You can almost think of it as an ES5 constructor function with much prettier syntax.
Instantiating an Object from an ES6 Class
Now that we have a class, we can now instantiate an object. We do this by making use of
the newkeyword like many other object oriented programming languages. This is how we,
“new up” an object.
class Vehicle {
}
let vehicle = new Vehicle();
So even though the “class” itself is a function, when we instantiate an object from that
class, we do get an actual object. In addition to this, if we test that the vehicle is an
instance of Vehicle, we do get back a true statement. This shows us that we can
determine the class of an instantiated object by making use of the instanceof keyword.
Adding a method to an ES6 class is great, because just like you can use a shorthand to
declare a function inside an object literal without the function keyword in ES6, you can also
use this shorthand syntax when creating a method inside a class. It’s a very nice and clean
syntax. In addition, if your editor supports it, you will also see a nice autocomplete feature
for your methods once they are declared.
// true
displayType() {
console.log('Car');
}
}
// Running Automatically
When we inspect the console, we see Running Automatically. notice all we did was new up
an object. We never actually call the constructor itself since it is automatic. Note there is no
comma after the closing curly brace of the constructor. Since we are used to working with
object literals where every key value pair is separated by a comma, you might be tempted
to add one between methods in a class. Don’t do it! You’ll throw an unexpected token error
if you do.
displayType() {
console.log('Car');
}
}
new somevariable();
// Running Automatically
Inheritance with extends and super in ES6
Let’s now create a class that inherits from another class. To do this, we make use of
the extendskeyword just like other object oriented languages. This allows the child class to
inherit all of the behavior of the parent class. We can extend our Vehicle class by building
a Tesla class to test out the functionality of extends.
class Vehicle {
constructor() {
console.log('Start me up');
}
}
// Start me up
Notice that the Tesla class is 100% empty, there is nothing between the curly braces.
When we run the code however, we get the message from the constructor of the parent
class of Vehicle. So even though Tesla has no constructor or methods in it, it does extend
Vehicle which does have a constructor. In ES6 when working with classes, that constructor
does get called when the child class is instantiated. Let’s see another example of this, but
this time we will pass in an argument to the constructor in the parent class.
class Vehicle {
constructor(color) {
console.log(`The car is ${color}`);
}
}
By calling super() in the Tesla child class, the JavaScript engine knows that it should
instantiate the parent class of Vehicle and call it’s constructor. This is why we see the
output of both classes in the console. In fact, if the child class has a constructor,
you must call super() in the child constructor. If you do not, you will get an error of
“Derived constructor must call super()”.
// Electric Powered
Even though the prototype gets overridden here, you do not need to specify any special
type of syntax to do so. Just re create the method in question in the child class, and it will
just work.
By calling super.getPropulsion(), the JavaScript engine will look up the prototype chaine
for a getPropulsion() method, and locates it in the Vehicle class (or constructor function).
We can achieve a similar result using Object Literals in combination with the
Object.setPrototypeOf() method. The example would translate to this code you see here.
let vehicle = {
getPropulsion() {
return 'Gas Powered';
}
};
let Tesla = {
getPropulsion() {
return 'Hybrid is ' + super.getPropulsion() + ' and Electric Powered';
}
};
Object.setPrototypeOf(Tesla, vehicle);
// Car
Here we have a class of Vehicle, and in the constructor we are setting this.kindof to a
simple string value of ‘Car’. The constructor method in Vehicle is very much like the way
you would specify a constructor function in ES5 which you would “new up”. Many times
you would accept values and set them via the this keyword when working like this.
Next we have our Tesla class which extends Vehicle. All we do in this class is to define a
constructor which calls super().
Finally, we new up a new instance of Tesla and assign it to car. We then log
out car.kindof and find the result of ‘Car’. The takeaway is that we initialize values in the
constructor using the this keyword as we did in ES5.
// Elcectric Car
// Gas
// Red
get height() {
return this.width;
}
set height(height) {
this.width = height;
console.log('Set a new height of: ' + this.height)
}
get area() {
return this.width * this.height;
}
}
square.height = 5;
console.log('Getting the height: ' + square.height);
console.log('Getting the area: ' + square.area);
square.height = 8;
console.log('Getting the height: ' + square.height);
console.log('Getting the area: ' + square.area);
function move() {
console.log('finished moving');
}
move(new Vehicle());
// moving forward
// finished moving
Here we have our Vehicle class as well as a function of move() defined. Note that when we
make a call to move() we pass in a new instance of the Vehicle class. The output shows
that the code runs and we get the output of the constructor functions of Vehicle, as well as
the logic from the move() function itself. You could even use this approach in a more one
off type of fashion by making use of an anonymous class like so.
function move() {
console.log('finished moving');
}
move(new class {
constructor() {
console.log('moving forward');
}
});
// moving forward
// finished moving
ES6 Class Tutorial Summary
We covered a lot of ground in this ES6 Class Tutorial, hopefully you enjoyed the material.
First we went over how to use the new class keyword to define a class in ES6. Next, we
learned how to instantiate an object from our class. We found we make use of
the new keyword, similar to how we might in other languages that support classes. After
this, we covered how you define a method inside your class. It is similar to how we might
define a method in an object literal, and we can omit the function keyword for a shorter
and easier to read syntax. Next up we covered how the class keyword is actually just a
new syntax that is easier to write and comprehend to set up constructor functions and
object prototypes. We saw that ES6 classes have support for constructor functions,
inheritance, method overrides, getters and setters, and static methods. Finally, we covered
the concept of classes acting as first class citizens in ES6 – which means they can be
passed around just like any other value in your program. Thanks for reading!
So here is a function named return_a_promise() that you guessed it, returns a promise.
You can see we declare a variable named promise and we new up a Promise object.
The Promise constructor accepts a function as an argument. The function passed as an
argument to the Promise constructor itself takes two arguments. The first is resolve, and
the second is reject. If we want the promise to be resolved and fulfilled, we can call the
resolve() function. If we run into an error condition, we would instead call the reject()
function. So we called neither in this first snippet yet when we inspect the console we see
“Fetching data, please wait.” then after a two second delay we see “Got the goods, nice
work.”
The function passed to new Promise executes immediately
What we wanted to see in this first example is simply that when you create a Promise, you
need to pass it a function. In addition, that function will execute immediately. This is the
reason we see the output already in the console.
promise.then(function () {
console.log('The promise is fulfilled!');
});
Notice that on the promise variable, we are now calling .then() passing it a function. All the
function does is to log out “The promise is fulfilled!” What is interesting however is that we
also added that call to resolve() up in the Promise constructor. See it up there? So what
we are doing here is simulating a call to a server to fetch data, or some type of
asynchronous action. The setTimeout() function is simply there to simulate a slight delay
while waiting for a resource. So after 2000 milliseconds, or 2 seconds, we log out “Got the
goods, nice work.” We are pretending we just got back the data we need from the server.
Well that’s great right? Since it succeeded, we should make a call to resolve(), and that is
exactly what we do here. So what does resolve() actually do?? Well, when we
call resolve() it actually notifies the promise of success and the first function which is
passed to .then() is called. It almost like an event listener. promise.then() is just sitting
around waiting for a promise to be fulfilled or rejected. Once it knows which it is, it takes
the appropriate action based on what is contained in the functions passed to it. In this
example here, it waits for 2 seconds, and since we have success, we call resolve()and
the appropriate code runs.
promise.then(function () {
console.log('The promise is fulfilled!');
}, function () {
console.log('The promise is rejected :-(')
});
This time around we are simulating a server error. So in the Promise you can see we are
trying to fetch some data. After two seconds, we find that we have an error code 500. Not
good. Not good at all. Since their has been a failure, we need to notify the promise of the
failure. That is exactly what we do when we call reject(). So since we call reject(), it is
now the second function passed to promise.then() which runs. This is the function which
handles a promise rejection or error state. In this scenario, we simply log out the bad new
that “The promise is rejected :-(” In summary we can see that promise.then() is an
important function which handles whether a promise was fulfilled or rejected in your
application.promise.then() takes two functions as it’s arguments. The first function runs if
the promise is fulfilled or successful, and the second function runs if the promise is
rejected or has failure.
promise.then(function (message) {
console.log(message + 'The promise is fulfilled!');
}, function (message) {
console.log(message + 'Whoops, something went wrong.')
});
Notice that we remove the logging we had before in the promise. This time around, we
simply call the resolve() function and pass it a string of ‘200 OK: ‘ as a parameter. We can
now get access to this value when we call the functions inside of promise.then(). So in
this example, we assume success from the server. For that reason we call resolve('200
OK: '); Do to success, the first function inside promise.then() runs. Notice we now accept
a message parameter to that function. When we log out the notification, we
include message as part of the notification. As such we see “200 OK: The promise is
fulfilled!” in the console. Great! For the sake of completeness here is the scenario of the
promise being rejected.
function return_a_promise() {
let promise = new Promise(function (resolve, reject) {
console.log('Fetching data, please wait');
setTimeout(function () {
reject('500 Internal Server Error: ');
}, 2000);
});
return promise;
}
promise.then(function (message) {
console.log(message + 'The promise is fulfilled!');
}, function (message) {
console.log(message + 'Whoops, something went wrong.')
});
return_a_promise().then(function (message) {
console.log(message + 'The promise is fulfilled!');
return 'Yeah!!';
}, function (message) {
console.log(message + 'Whoops, something went wrong.')
}).then(function (message) {
console.log('Seriously, time to party! ' + message);
});
Since the promise is successful, we call resolve(). This fires the first function passed
to then(). Notice that in that function, after we log out the message, we have a line where
we return “Yeah!!”. This value now becomes available to the next call to then(). See how
it is chained on to the end of the first then(). When then() is called the second time, it is
also accepting a message argument however instead of this value coming from resolve(), it
is coming from what we returned out of the first then() call. Hopefully that makes sense!
Chaining of functions is pretty common when using Promises, as well as in other aspects
of JavaScript.
return_a_promise().then(function (message) {
console.log(message + 'The promise is fulfilled!');
}).catch(function (message) {
console.log(message);
});
function return_a_second_promise() {
let promise = new Promise(function (resolve, reject) {
console.log('Requesting CDN data, please wait');
setTimeout(function () {
resolve('Faster image load from CDN.');
}, 2000);
});
return promise;
}
return_a_promise().then(function (message) {
console.log(message + ' The promise is fulfilled!');
}).catch(function (message) {
console.log(message);
});
To help bring the concept home, we show a little screen capture here of the result
happening in real time. This gives us a better idea of how the two asynchronous calls are
working.
return_a_promise().then(function (value) {
console.log(value);
}, function (reason) {
console.log(reason);
});
// Here is your data
Calling Promise.reject()
function return_a_promise() {
return Promise.reject('Fail!');
}
return_a_promise().then(function (value) {
console.log(value);
}, function (reason) {
console.log(reason);
});
// Fail!
// Hi from promise 1
// Promise 1 resolved
// Hi from promise 2
We’ll look at one last example of Promise.all() vs Promise.race() to fully understand how
they work.
Promise.all() Example
let promise1 = new Promise(function (resolve, reject) {
setTimeout(function () {
console.log('Hi from promise 1');
resolve('1 worked');
}, 1000);
});
// Hi from promise 1
// Hi from promise 2
// ["1 worked", "2 worked"]
Promise.race() Example
let promise1 = new Promise(function (resolve, reject) {
setTimeout(function () {
console.log('Hi from promise 1');
resolve('1 worked');
}, 1000);
});
// Hi from promise 1
// 1 worked
// Hi from promise 2
With this info in mind, our tutorial covered a lot of ground. We learned about the Promise
object, and how to create a function that returns a promise. Since promises involve
asynchronous calls, we used the JavaScript setTimeout function to simulate this in our
many examples. We also observed that when using promises we will make use of
the resolve(), reject(), all(), race(), and then() methods to handle the results of a promise.
Great Work!
Iterators In ES6
Iterators are a major new feature in ES6, and are used extensively already.
Iterators are used for lazy evaluation, or in cases where describing an infinite
sequence is needed. Soon we will be looking at Generators, and it helps to
have a grasp of iterators before we do so. In fact, Iterators are kind of a
prerequisite for Generators, Promises, Sets, and Maps. Let’s look at the basics
of Iterators here, and get up to speed with them.
Introduction to Iterators
ES6 now has what’s known as an iterable protocol. It is a protocol that defines the iterating
behavior of JavaScript objects. An iterable object has an iterator method with the
key Symbol.iterator that returns an iterator object. Let’s see how.
let numbers = [100, 200, 300];
console.log(typeof numbers[Symbol.iterator]);
// function
Here we have a simple array of numbers and this is stored in the variable numbers. It turns
out, arrays in ES6 now have a special property which can be accessed with the bracket
notation we see here. In fact the property name is a symbol, which is also another new
feature in ES6. Symbols are just a way to guarantee a unique value. When we log out the
typeof this property, it is a function. Interesting! Let’s go a little further.
let numbers = [100, 200, 300];
let iter = numbers[Symbol.iterator]();
console.log(iter.next());
So check it out. Since Symbol.iterator is a function, that means we can call it. That is
exactly what we do on line 2 right above. We assign this result to the iter variable, which
is our iterator. That iterator has some special functions associated with it. In this example
we call .next() on the iterator and our result is a special object which has two properties
of value and done. We see at this time, value is 100 and done is false. This makes since
since we are on the first element of the array, and out iterator has not cycled through all
the values. Let’s see multiple calls to the iterator now.
let numbers = [100, 200, 300];
let iter = numbers[Symbol.iterator]();
iter.next();
iter.next();
console.log(iter.next());
Each call to .next() produces the next value in the array. Oddly, the done property is still
set to falseeven though we are on the third and final value. Hmmm. Let’s make another
call to .next().
let numbers = [100, 200, 300];
let iter = numbers[Symbol.iterator]();
iter.next();
iter.next();
iter.next();
console.log(iter.next());
On the N + 1th time we call the .next() function based on the size of the array, we will
then reach a done state of true in the iterator object. At this point the value will be set
to undefined. In other words, if you have an array with a size of 3, you would need to
call .next() four times in order to exhaust the iterator.
Making Your Own Iterator
Iterators are built into arrays, but we can custom make an iterator if we like. We’ll create an
object literal named numberGen and give it a property of [Symbol.iterator] similar to how
arrays have that property. Then we have a local variable of nextNum set to 500, and we
return a function named next() which returns an iterator object that has
our value and done properties. When we run the code and make a couple of calls
to .next(), we can see the initial value of 500 and the next value of 501. Each call
to .next() will increment by one. Pretty cool!
let numberGen = {
[Symbol.iterator]() {
let nextNum = 500;
return {
next() {
return {
value: nextNum++,
done: false
}
}
}
}
};
// 500
// 501
// 500
// 501
// 502
// 500
// 501
// 502
// 503
// 504
// 505
process(...numbers);
// 20
let iterableObject = {
[Symbol.iterator]() {
return Object.assign({}, countingIterator)
}
};
Again, notice that the state of the iteration maintains each time. In this example above, we
are taking a slightly different approach and making use of Object.assign. What this does is
to make a shallow copy of the iterator object every time an iterator is returned from the
function. By using this approach, you can have several iterators on the same iterable
object which each have their own internal state. If we didn’t use Object.assign, there
would just be several references to the same exact iterator object.
console.log(vehicles.entries());
// SetIterator {["Car", "Car"], ["Truck", "Truck"], ["Semi", "Semi"]}
console.log(vehicles.keys());
// SetIterator {"Car", "Truck", "Semi"}
console.log(vehicles.values());
// SetIterator {"Car", "Truck", "Semi"}
console.log(make.entries());
// MapIterator {[1, "Tesla"], [2, "Honda"], [3, "Mack"]}
Sets and Maps are iterable in their own right, so it is not even necessary to create these
iterators with the keys, values, or entries method. Since Sets and Maps are iterable
themselves, they can be used in for-of loops like you see here.
for ( let [key, value] of make ) {
console.log( key, value );
}
// 1 "Tesla"
// 2 "Honda"
// 3 "Mack"
Iterators In ES6 Summary
Iterators in ES6 are a welcome addition to ES6. You will often find them in the context of
Generators, Promises, Maps, and Sets. Here is a summary of our learning about Iterables
in ES6.
ES6 Generators
Generators in ES6 are a special kind of function that return an iterator. They are
quite a bit different than your standard run of the mill function in JavaScript
however. Generators can pause themselves as they are running, and return
multiple values as execution pauses and resumes. You use an iterator to call a
generator multiple times. Let’s look at some examples to better understand how
generators work.
Defining a Generator Function
function *generateit() {
yield 200;
yield 300;
}
Notice the asterisk just in front of the generateit() function. This * symbol indicates that
we are dealing with a generator function. In addition to this, we can see these new
statements inside the function that make use of the yield keyword. The function yields a
value of 200, and it also yields a value of 300. Once both values are yielded, the function
will exit. Next up, we actually run the generateit() function, and it assigns an iterator in a
paused state to the variable iter. When we log out the value of iter.next(), we see the
result of Object { value: 200, done: false }. So in essence, the function paused at the first
yield statement. The following is the result of multiple calls to iter.next():
let iter = generateit();
iter.next();
console.log(iter.next());
By this code and output, we see that a generator completes just like an iterator does.
Yielding Indefinitely
In this example, we’ll create a generator function that can yield indefinitely. In other words,
it can never be exhausted. Rather than having hard coded values like our first examples of
a generator, here we will use some logic inside the generator function to set a starting
point, and then an increment operation on every yield.
function *generateit() {
let nextNum = 400;
while (true) {
yield(nextNum++);
}
}
// 401
// 400
// 401
// 402
// 403
Let’s wrap the second call to iter.next() in a console.log() statement. The first line still
shows the same The result is 777 from the generator, however we now also get to inpsect
the iterator object. That object has value set to undefined, and done set to true. This is
because once we passed 777 to iter.next(), there was no further yield in the generator –
so at that point, it is done.
function *generateit() {
let result = yield;
console.log(`The result is ${result}`)
}
This example sets up a new array, and then initializes it’s value to 3 yield keywords. After
that, we want to log out the arrayOfYields to see what it contains.
With this in place, we call the generator, then call iter.next() four times. Once to initialize,
and then three more times passing in a value to be placed into the array on each call.
Inspecting the console shows us the final array of [ “PHP”, “JavaScript”, “Linux” ].
When using the yield keyword in an expression, you should wrap it in parenthesis as a
good practice. If you don’t, you might not get the results you expect. In the following
example, we want to make use of multiplication in our generator function. We wrap the
yield in parenthesis to make things work, otherwise yield is ignored and the expression
fails.
function *generateit() {
let result = 5 * (yield);
console.log(result);
}
// 10
// 77
// Array [ "Node", "Angular", "React" ]
// undefined
// 77
// Node
// Angular
// React
// undefined
throw and return in Generators
It is possible to get a finer degree of control over iterators by making use of
the throw and returnkeywords. Let’s inspect a few examples to see how they operate.
The following snippet has a generator that yields three values. Notice that they exist in a
try / catch block. Following the generator definition, we kick off the generator as normal,
then log out a few values. The first value logged out is that of ‘Fruit’. After this however, we
make a call to iter.throw(), and pass in a message of ‘Hey now’. The result of his call is
that we receive an object with value set to undefined, and done set to true. What this
means is that an exception was thrown, and handled by the catch block. We don’t have
any logic in the catch block, so it kind of fails silently. On the final call to iter.next(), the
generator has already completed so we get the object with value set to undefined and
done set to true.
throw in generators
function *generateit() {
try {
yield 'Fruit';
yield 'Coffee';
yield 'Oatmeal'
} catch (e) {
}
}
// Fruit
// Object { value: undefined, done: true }
// Object { value: undefined, done: true }
If we omit the try catch block from the generator, the first value still gets printed out. When
we hit iter.throw(), and exception is thrown but the generator has no catch logic so it
terminates the script entirely. This is why we don’t see any object on the final call
to iter.next(). The takeaway is, if you want to call iter.throw() in your code, you should
ensure you have a try catch block to handle it.
function *generateit() {
yield 'Fruit';
yield 'Coffee';
yield 'Oatmeal'
}
// Fruit
// Uncaught Exception: Hey now
return in generators
Making use of the return function is a way to clean up your generators. Below we make
use of our familiar generator function, kick it off, then log out the first value. After this, we
see something new in console.log(iter.return(‘Hey now’)); When this is called, we can see
in the output that we get an object with value set to ‘Hey now’ and done set to true. The
final call to iter.next() gives us the familiar finished iterator object with value set to
undefined and done set to true. Calling return on an iterator is a nice way to wrap up the
iterator and complete it’s execution. Whatever the parameter is that gets passed
to iter.return() becomes the value of the returned object. Since we called return, we never
make it to ‘Coffee’ or ‘Oatmeal’ in the generator. The return function finished it.
function *generateit() {
yield 'Fruit';
yield 'Coffee';
yield 'Oatmeal'
}
// Fruit
// Object { value: "Hey now", done: true }
// Object { value: undefined, done: true }
Iterator functions are a tricky topic in ES6, and it will take some time to become familiar
with them. As ES6 matures and we see it more out in the wild, more practical applications
of generators will become available to see how to best make use of them.
1. Array.of()
To learn about the new Array.of() function, let us first take a look at a strange little quirk in
ES5 concerning using the Array constructor. We’ll set up an array of prices, then take a
look at the length of the array.
let prices = Array(5000);
console.log(prices.length);
// 5000
When the code runs, it tells us that we have an array with a length of 5000. What?! We
only passed one value, 5000, into the array. Well in ES5, if you pass just one value to the
array constructor which is numeric, an array of that size will be created. That is kind of
strange, don’t you think? This is the purpose of Array.of(). Let have a redo with our new
function.
let prices = Array.of(5000);
console.log(prices.length);
// 1
In this go round, we find the length of prices to be 1. That seems to make much more
Nice!
sense. Array.of() is a new way of creating an array which fixes this odd behavior in ES5. If
you create an array with just one numeric value, the array is created with just that value
and not the amount of that value.
2. Array.from()
Let’s see how the new Array.from() function works. Below we have set up an array with
three values of 500, 700, and 1000. On the second line, we make a call to Array.from() and
pass in prices as the first argument, and an arrow function as the second argument. By
running the code, we see that the prices are now taxed at 5 percent. Array.from() creates a
brand new array based on prices, and for each element in that array the arrow function is
called. So basically we take each price and multiply it by 1.05 denoting a tax rate of 5
percent.
let prices = [500, 700, 1000];
let taxed = Array.from(prices, price => price * 1.05);
console.log(taxed);
console.log(totalprice);
What is happening here is that the third argument to Array.from() is an object which
becomes this in the function. That is why we are able to take the price and
add this.listingfee to give us the total price. Note that when using this technique, we
need to use a standard function as opposed to an arrow function for the second argument
to Array.from(). This is because arrow functions do not allow meddling with the this value.
3. Array.fill()
ES6 now gives you an easy way to fill up an array using Array.fill(). Let’s see a quick
example.
let prices = [500, 700, 1000];
prices.fill(2000);
console.log(prices);
So it looks like this function will overwrite any existing values in all keys of the array with
the provided value. Since we call .fill() on the prices array which has 3 elements in it,
all elements in the array are now 9000. There is also an option to pass a second argument
to Array.fill() in order to start at a specific index. Let’s see how to do that.
let prices = [500, 700, 1000];
prices.fill(2000, 2);
console.log(prices);
By passing the value of 2 as the second argument, we are telling the fill function to start
filling the array at the 2nd index. Since arrays are 0 based as we know, it is the third value
in our array that gets overwritten with the value of 2000.
Now, why only pass two arguments when you can pass three?! Here we will pass another
argument to Array.fill(). This will demonstrate that the second argument specifies what
index to start at while the third argument specifies where to stop. Check it out now.
let prices = [500, 600, 700, 800, 900, 1000, 1500];
prices.fill(2000, 2, 4);
console.log(prices);
We added a few more values to our original array so that it is a bit easier to see how this
works. Notice that we begin filling with the value of 2000 at index 2 and stop at index 4.
Note that the filling stops before actually placing a value in the index. This is why you see
only index 2 and 3 with the value of 2000.
4. Array.find()
Array.find() is another new function added to arrays in ES6. You can use it to easily find a
value in an array that meets a given criteria. Let’s see how it works.
let prices = [500, 600, 700, 800, 900, 1000, 1500];
let result = prices.find(price => price > 777);
console.log(result);
// 800
Notice that we pass an arrow function to the .find() function. That function is applied
against every element in the array, and as soon as it finds a value that meets the criteria,
that value is returned. It does not continue to return all values that meet the criteria. This is
why we only get one result in this example. Let’s run through this example just one more
time to see it in action.
let prices = [500, 600, 700, 800, 900, 1000, 1500];
let result = prices.find(price => price < 777 && price > 600);
console.log(result);
// 700
5. Array.findIndex()
In addition to Array.find(), we now also have the Array.findIndex() function which works in
a similar way but instead of returning the value, it returns the index. Let’s see how it works.
let prices = [500, 600, 700, 800, 900, 1000, 1500];
let result = prices.findIndex(function (price) {
return price == this;
}, 1000);
console.log(result);
// 5
Here we use a regular JavaScript function passed into the .findIndex() function. We simply
return the result of price being equal to this. this is set to 1000, which is the second
argument to .findIndex(). We can see that the value of 1000 lives at index 5 of the zero
based array.
6. Array.copyWithin()
Array.copyWithin() is an interesting addition to the array function library in ES6. With it,
you can copy values inside the array just like the name implies. It takes a value from one
index, and places it in another. Here is an example.
let prices = [500, 600, 700, 800, 900, 1000, 1500];
prices.copyWithin(3, 1);
console.log(prices);
The key to understanding copyWithin() is what the arguments mean. Argument 1 is the
index which will be overwritten. It is where data will be copied to. The second argument is
the data to copy from. So in our example, we are saying that we are going to copy the data
at index 1 (600) and paste it into index 3 (800). After the function runs, we see that index 3
no longer holds 800, it now holds 600. It is working as expected. There is also the option to
pass a third argument to copyWithin(). This third argument tells us how many items to
copy. Let’s see how it works.
let prices = [500, 600, 700, 800, 900, 1000, 1500];
prices.copyWithin(2, 0, 3);
console.log(prices);
The destination index is 2, or the third value in the array. We start copying form index 0, or
the first value in the array. We are going to copy three successive values starting at index
0. So the result correctly displays 500 in the 2nd index position, followed by two additional
copied values of 600 and 700. Index 5 and 6 are unaffected and so they contain their
original values of 1000 and 1500.
7. Array.entries()
The Array.entries() function is a really cool addition to the language. It takes an array, and
creates a listing so to speak of each entry. Let’s examine closely how it works.
let words = ['Lenovo', 'Tablet', 'Coffee'];
console.log(words.entries());
// Array Iterator { }
First up, we simply set up an array of words. Then we log out the value of calling .entries()
on that array. Interesting! It results in an array iterator. Hmm, well we learned that we can
call the .next() function on iterators, so let’s try that out!
let words = ['Lenovo', 'Tablet', 'Coffee'];
console.log(words.entries().next());
Awesome! We can see that we get the first list so to speak of the array. The iterator object
is not done, so it is set to false. However the value contains an array which holds two
values. At index 0 of that array is the index of where Lenovo lives. That is index 0. At index
1 is the value itself, which is Lenovo. Very neat. Finally, since we know we can use
the spread operator on iterators, let’s go ahead and do that now.
let words = ['Lenovo', 'Tablet', 'Coffee'];
console.log(...words.entries());
// Array [ 0, "Lenovo" ]
// Array [ 1, "Tablet" ]
// Array [ 2, "Coffee" ]
The .entries() function gives us the index / value pair of the array.
8. Array.keys()
Array.keys() works in a similar way to Array.entries() except that it only provides the keys
of the array. See it in action now.
let words = ['Lenovo', 'Tablet', 'Coffee'];
console.log(...words.keys());
// 0 1 2
9. Array.values()
Finally, we have our Array.values() function which is similar to the prior two examples but
provides only the values at each key. Observe young Jedi.
let words = ['Lenovo', 'Tablet', 'Coffee'];
console.log(...words.values());
ES6 includes two data structures which help programmers get work done
without reinventing the wheel. These two data structures are those
of Sets and Maps. A Set can be thought of as a collection of elements which
are both unordered, and unique. That is the key to remember. The purpose of a
Set is to guarantee the uniqueness of it’s items. A particular element is a
member of the set, if the set contains the element. The set does not change if
you add an element which is already a member of the set. A Map on the other
hand is a collection of key-value pairs. They are quite similar to objects,
however maps can have keys of any type, and the keys are not converted to
strings. Let’s expand our learning of Sets and Maps in ES6 right now.
ES6 Sets
Sets are collections that with deal with single values or single objects. There is no mapping
from a key to a value such as you might find in a Map. Like we mentioned in the
introduction, a Set is to group together items and guarantee their uniqueness. As always,
let’s look at some code.
Using .add() to add elements
let pouch = new Set();
pouch.add('Weapons');
pouch.add('Bows and Arrows');
pouch.add('Shields');
console.log(pouch.size);
// 3
Above we initialize a new Set and assign it to the pouch variable. Once we have that set, it
is easy to add items with the .add() function. We log out the size of the set after adding
Weapons, Bows and Arrow, and Shields, to see that we do indeed have three unique
items in the set. Recall we said that you can not add an item to the set twice? Let’s prove
that here.
let pouch = new Set();
pouch.add('Weapons');
pouch.add('Bows and Arrows');
pouch.add('Shields');
pouch.add('Weapons');
console.log(pouch.size);
// 3
We add another set of Weapons, but check it out. The size still shows as 3.
console.log(pouch.size);
// 3
Just like with the .add() function, if you pass an array of values to the Set Constructor,
duplicates will be ignored. For example, let’s see how this works here.
let pouch = new Set([
'Korok Seed',
'Sheikah Slate',
'Spirit Orb',
'Korok Seed',
'Sheikah Slate',
'Spirit Orb',
]);
console.log(pouch);
// Set [ "Korok Seed", "Sheikah Slate", "Spirit Orb" ]
So even though we had an array of 6 items, only 3 were added to the set. This is because
3 of them are duplicates, and duplicates are not added to a set.
console.log(pouch.has('Armor'));
console.log(pouch.has('Ancient Battle Axe'));
// true
// false
console.log(pouch);
// Set [ "Sheikah Slate", "Spirit Orb", "Paraglider" ]
console.log(...keyItems.keys());
console.log(...keyItems.values());
console.log(...keyItems.entries());
From this, we can see that .keys() and .values() give the same results. That is to say, each
value is both the key and the value. When we make a call to .entries(), we confirm this as
we see an array which has the value in both the key and value positions.
// Biggorons Sword
// Blizzard Rod
// Boat Oar
// Boko Bat
// Boko Club
// Boko Spear
// Biggorons Sword
// Blizzard Rod
// Boat Oar
// Boko Bat
// Boko Club
// Boko Spear
weapons.clear();
console.log(weapons);
// Set [ ]
Weak Set
We also have Weak sets in ES6. The main difference between Sets and Weak Sets is that
their elements may disappear once they are garbage collected. The use cases for weak
sets are probably not large but we include them here for completeness. Weak sets are not
iterable, can only store objects, and you don’t have access to the size of the set like you do
with normal sets. In any event, let’s look at a weak set here.
let object1 = { name: 'Zelda'};
let object2 = { name: 'Link'};
let characters = new WeakSet([object1, object2]);
console.log(characters);
ES6 Maps
A map is simply a key value pair very much like an object in JavaScript. You could
consider any JavaScript object to be a map. What makes this new form of a Map unique, is
that you can use an object as a key. This was not possible with the standard JavaScript
object. Let’s see a few examples of using an object as the key in Maps.
let player1 = { name: 'Mario'};
let player2 = { name: 'Luigi'};
console.log(players.get(player1));
console.log(players.get(player2));
// Super Mario!
// Awesome Luigi!
Here we set up two variables which each holding an object. We go ahead and create a
new Map and store that in the players variable. We then use the .set() function to place a
value in a given key. Note here that we place a value in the key of player1, and player2.
When we log out the value of each key in the players map, we get Super
Mario! and Awesome Luigi! So as we can see, we are actually using an object as the key
in this map. Very neat.
console.log(players.size);
// 2
items.delete(item1);
console.log(items.size);
// 1
shields.clear();
console.log(shields.size);
// 0
Passing an iterable to the Map constructor
In this example we first set up an array of objects. From there we create a map, passing in
the iterable to populate our map. We then simply check it’s size, and get the two values
held in the map.
let shield1 = {name: 'Ancient Shield'};
let shield2 = {name: 'Boko Shield'};
let shieldarray = [
[shield1, 'Emblazoned Shield'],
[shield2, 'Fishermans Shield']
];
// 2
// Emblazoned Shield
// Fishermans Shield
We can make use of the spread operator when working with Maps as we see here. First
we check the .values() and then we check the .entries().
let shield1 = {name: 'Ancient Shield'};
let shield2 = {name: 'Boko Shield'};
let shieldarray = [
[shield1, 'Emblazoned Shield'],
[shield2, 'Fishermans Shield']
];
let shieldarray = [
[shield1, 'Emblazoned Shield'],
[shield2, 'Fishermans Shield']
];
// Emblazoned Shield
Weak Maps
With a weak map, it holds a weak reference to the object. When one of those keys such as
shield1 or shield2 gets garbage collected, it automatically gets removed from the weak
map. In this example below, we set the key shield1 of the weak map to null. This makes it
ready for garbage collection. So when we go to log out the size of our weak map, we find
that it is undefined.
let shield1 = {name: 'Ancient Shield'};
let shield2 = {name: 'Boko Shield'};
console.log(shieldmap);
shield1 = null;
// garbage collection
console.log(shieldmap.size);
One area of JavaScript has definitely needed some help with in the past is
working with strings. Traditionally, there hasn’t been a lot of built in methods to
deal with common string processing scenarios. You could get things done
with regular expressions just fine, but it would be nice to have methods
dedicated to string processing much like covered with all of the PHP String
Functions. We don’t quite have the kitchen sink now in JavaScript, but there are
many useful additions and we’ll check them out in this article.
string.startsWith()
The startsWith() method operates like so: stringOne.startsWith( stringTwo ) is true if and
only if stringOne starts with stringTwo. With this understanding, we can set up a few
examples here of checking a string to see if it starts with a particular different string.
let gamesystem = 'Nintendo Switch';
if (gamesystem.startsWith('Nintendo')) {
console.log('The console is made by Nintendo');
}
if (gamesystem.startsWith('Nintendo')) {
console.log('The console is made by Nintendo');
}
// The console is made by Nintendo
if (gamesystem.startsWith('Nintendo')) {
console.log('The console is made by Nintendo');
} else {
console.log('The console is made by another vendor.')
}
string.endsWith()
Similar to the startsWith() method, we also have an endsWith() method. These are great
little methods since it is common to check a string for beginning or ending values.
The endsWith() method works like so. stringOne.endsWith( stringTwo ) is true if and only
if stringOne ends with stringTwo. Let’s again look at a few example of this in action.
let game = 'The Legend of Zelda';
if (game.endsWith('Zelda')) {
console.log('Playing Zelda');
} else {
console.log('Not Playing Zelda')
}
// Playing Zelda
if (game.endsWith('chips')) {
console.log('How do you like Snipperclips?');
} else {
console.log('You should get Snipperclips')
}
string.includes()
How often do you need to check if a string contains another string? Like every day,
amiright? Well now you have this handy method in ES6 to do this quickly. It works as
follows. stringOne.includes( stringTwo ) is true if and only if stringTwo is a substring
of stringOne. Let’s test it out now.
let controller = 'Does the Nintendo Switch have two Joy-Con controllers?';
if (controller.includes('Joy-Con')) {
console.log('Indeed!');
} else {
console.log('Noooooo!');
}
// Indeed!
if (controller.includes('Pro')) {
console.log('You have built-in amiibo functionality!');
} else {
console.log('Time to Level Up');
}
if (controller.includes('Charging')) {
console.log('Combine the left and right Joy-Con into one larger controller');
} else {
console.log('I need to get a Charging Grip');
}
// Combine the left and right Joy-Con into one larger controller
string.repeat()
The string.repeat() method works like this. string.repeat( num
) replicates string, num times, and joins them together.
let double = 'Nintendo'.repeat(2);
console.log(double);
// NintendoNintendo
New String Methods In ES6 Summary
In this tutorial, we learned a bit about the new string methods available to developers in
ES6. While not quite as incredible as some of the other new features we’ve been covering
lately, hopefully you do find this additions to the language helpful!
Chapter 5: WordPress
What is WordPress?
What is WordPress?
Simple Blogging Application
For many of us that maybe are not full blown geeks, but use the internet on a regular
basis, we might be casually familiar with WordPress as a simple blogging application.
Maybe your friend does some blogging, and you remember her mentioning using
WordPress. So yes, you can use WordPress as a simple blogging application and it works
great for this.
Open Source
So this WordPress Software you keep telling me about, what’s it going to cost me? Well,
it’s free. As in, beer or pizza. That’s right, this powerful software is free for you to
download, use, modify, customize, and tinker with in any way you see fit. You can thank
the good folks over at http://automattic.com for this!
Created in 2003
Since WordPress began in 2003, there have been over 82 great feature updates, and
countless improvements and refinements to lead up to what it is today. You’ll be amazed
to learn that approximately 19% of all websites on the entire internet are powered by
WordPress! In addition to this, every one in four new websites starting today will leverage
WordPress in some way. It is truly an amazing success story.
Sony Music
LinkedIn
Techcrunch
GigaOM
Media Temple
Playstation Blog
Smashing Magazine
Better Codes
SitePoint
Nettuts
Web Development Group
As you can see, there are many well known people, brands, and businesses using
WordPress.
WordPress
When we say WordPress, we’re referring to the actual software itself that makes up the
WordPress Application. This is for the folks that are ready to build and configure websites
on their own. You’ll need to understand how to download your own copy of the software,
register a domain name, purchase dedicated web hosting, and so on. There are many
many pieces to the puzzle, which is why you see so many blogs that focus on nothing
other than helping others get their blogs up and running!
Pros: Full Control, Full Customization
Cons: More Work
WordPress.org
WordPress.org is where you can visit to download the actual WordPress Software to your
local environment. You’ll find various downloads, plugins, and information to help you
along. In addition you can visit the user forums, find new themes, and browse the
extensive documentation for creating and updating content in WordPress.
WordPress.com
Maybe you don’t want to deal with downloading your own copy of WordPress, setting up
your own hosting account, registering a domain name, and all of the manual legwork that
is involved. Turnkey blogging is more along the lines of what your’re looking for. In that
case WordPress.com is here to fill that need for you. WordPress.com is a cloud based
service that will get you up and running in mere minutes.
Pros: Easy
Cons: Limited ability to customize
When you’re looking to set up a new blog or website and you need to decide between Self
Hosted WordPress vs Cloud Hosted WordPress.com, it really comes down to what you
want to get out of the blogging experience. If you need full control, and if you’re reading
this blog you probably do want that, go for the self hosted WordPress option. If you’re not
ready to make the full commitment you can start at WordPress.com and then export that
data into your own self hosted solution if you like at a later time.
Install WordPress
In this series we’re most interested in working directly with WordPress the application.
We’ll make use of a WordPress Install on our localhost. You can do the same if you’d like
to follow along with hands on exercises. The easiest way to do this is to install something
like mamp if you’re on a mac, or wamp if you’re on a windows platform. The great thing
about these products is that they will install Apache, PHP, phpMyAdmin, and everything
else you’ll need to get WordPress up and running very quickly. If you prefer, you can also
set up your own self hosted option using something like Laravel Forge. Feel free to use
whatever you like.
Once you enter your correct credentials, you’ll be routed to the administrators area of your
WordPress Site. Maybe you already logged in recently and your session is still active, in
this case you wouldn’t even need to enter your credentials. By simply visiting the admin url
of your WordPress site, it will take you right to the admin area. It looks a bit like this if you
are not already familiar:
From the administrators panel of WordPress, you can do an amazing range of things with
your website. Straight away you’ll likely visit the settings menu and configure things like
like the Site Title, Tagline, WordPress Address, Site Address, Email Address, Timezone,
and much more. The Site Title is the actual name of your site. For this website, it is simply
VegiBit. The tagline is a few words that explain what your site is all about. If you write
about Cup Cakes, you might have a tagline something like, “The Best Tasting Cakes This
Side of the Mississippi” or something else you find catchy. Ours is simply, “Random Bits of
Awesomeness”. The WordPress address and the Site address will usually be the same.
You would simply put http://yourdomain.com/ or something similar to this in these fields.
How do I log out of WordPress?
A fairly simple yet easy to forget idea is logging out of WordPress. In most cases, you don’t
really need to worry about this. There are instances when you would in fact want to make
sure you are logged out of WordPress. Consider if you work in an environment which has
a few pranksters lurking about. Imagine you just finished a masterpiece of a WordPress
post when suddenly nature calls. You walk away from your workstation and visit the
bathroom as needed. Your buddy notices that you had left and sees that there is a post
just waiting to be published. Said buddy comes over and swaps out a few pictures in the
post for pictures of you from last Friday Night when things got a little unruly at the company
party. Our friend then decides to publish the post, and for good measure shares to Twitter,
Facebook, and Google Plus just to be sure the message gets out…
The chances of this actually happening are very high not really that high. In this scenario,
you need to be sure you know how to log out of WordPress! That way the mischievous
minions in your office won’t hack your latest blog post. In the very upper right corner of the
administrators panel you’ll see an icon of your gravatar in addition to your user name. It will
likely say something like, “Howdy, Username” (Insert your username here). Simply hover
over this area, then click on “Log Out”. You’ll be happy you did the next time you need to
visit the rest room.
We have lots more WordPress to Cover!
There are going to be several posts in this series that examine the nuts and bolts of
WordPress. The goal is to cover everything we possibly can, soup to nuts. It’s going to be
a lot of fun, and we hope you’ll stick around for the fun.
We have a fresh copy of WordPress installed on our localhost, it’s now time to start
looking under the hood a bit to see how this all fits together. A great place to start is
with the WordPress Admin Panel, also known as the Dashboard. By getting a strong
grasp on the ins and outs of the WordPress Dashboard, you’ll save yourself time and
frustration as you set out creating your site. In addition, you’ll be in full control of your
content, themes, plugins, and general appearance. Let’s look at the WordPress
Dashboard now!
Welcome to WordPress!
When you first log in to the administrators panel in WordPress, you’ll be greeted with an about page that tells you all
about the version of WordPress currently installed. It’s broken up into three main parts.
What’s New
http://localhost/wordpress/wp-admin/about.php
In the What’s New section, you’ll find a description of all the latest updates for the particular version of WordPress
installed. WordPress is always striving to make the content creation process easier for you by providing streamlined
media management, ease of plugin installation, effortless embedding, and easy photo manipulation.
For example, one of the most incredible, and quite frankly ridiculously awesome new features is the ability to embed
third party content by simply pasting an url into the editor. Want to a tweet or a facebook post in your article? Easy as
pie:
Just paste something like this in your
editor https://twitter.com/vegibit/status/509858080859758593 on it’s own line and BOO YEAH!
Follow
vegibit @vegibit
What is WordPress? http://wp.me/p3iC3e-30i
8:16 PM - 10 Sep 2014
What is WordPress? - Vegibit
Depending on your background, you may be familiar with WordPress or it might be a new term to you. This series of
episodes will focus on WordPress for thos
vegibit.com
Retweets
likes
Credits
http://localhost/wordpress/wp-admin/credits.php
These are the people that make it happen. In this page, you’ll find the Project Leaders, Contributing Developers, Core
Contributors, and all External Libraries used in the WordPress Project. We can thank these folks and software packages
for making WordPress the excellent piece of software that it is.
We can also see the list of fantastic 3rd party software that helps make WordPress tick.
Backbone.js, Class POP3, Color Animations, Horde Text Diff, hoverIntent, imgAreaSelect, Iris, jQuery, jQuery UI,
jQuery Hotkeys, jQuery serializeObject,jQuery.query, jQuery.suggest, jQuery UI Touch Punch, json2, Masonry,
MediaElement.js, PclZip, PemFTP, phpass, PHPMailer, Plupload, SimplePie,The Incutio XML-RPC Library, Thickbox,
TinyMCE, Underscore.js, and zxcvbn.
Freedoms
http://localhost/wordpress/wp-admin/freedoms.php
This section talks a bit about WordPress and the Philosophy behind it. If you’re going to be a WordPress user, it is worth
your time to take a closer look at this page to become familiar with the project. Four key points are discussed here that
are numbered in zero based math – you gotta love programmers! They are quoted as follows:
You have the freedom to run the program, for any purpose.
You have access to the source code, the freedom to study how the program works, and the freedom to change it
to make it do what you wish.
You have the freedom to redistribute copies of the original program so you can help your neighbor.
You have the freedom to distribute copies of your modified versions to others. By doing this you can give the
whole community a chance to benefit from your changes.
You can also drag and drop the areas to fit where ever you’d like them to appear. Want that Activity box in the lower
right hand section of the screen? No problem, just drag it over there and drop it in place. Personally, I really like the
defaults. Defaults exist for a good reason, not only in WordPress, but in all areas of software, technology, and more.
Think about it, the creators of a product or device want you the consumer of said product to have the best possible
experience with it. When they choose the default configuration of their creation, they are doing so because it is likely to
work well for the largest range of potential people as possible. Then again, the defaults may not work for you as we’re all
different! Long story short, arrange things however you like to fit your needs!
Need Help?
Of course, we all need help sometimes! In the far upper right portion of the Dashboard area next to the Screen Options is
a Help Tab. Don’t be afraid to click that baby! In the help section you’ll find a wealth of very valuable information as
you navigate the vast landscape that is WordPress. What’s great about this help feature is that it is contextual, meaning
that depending what page of the WordPress Dashboard you are currently on, this menu will update to provide the best
information to you. For example, the Dashboard help area looks something like this.
Overview
Welcome to your WordPress Dashboard! This is the screen you will see when you log in to your site, and gives you
access to all the site management features of WordPress. You can get help for any screen by clicking the Help tab in the
upper corner.
Navigation
The left-hand navigation menu provides links to all of the WordPress administration screens, with submenu items
displayed on hover. You can minimize this menu to a narrow icon strip by clicking on the Collapse Menu arrow at the
bottom.
Links in the Toolbar at the top of the screen connect your dashboard and the front end of your site, and provide access to
your profile and helpful WordPress information.
Layout
You can use the following controls to arrange your Dashboard screen to suit your workflow. This is true on most other
administration screens as well.
Screen Options – Use the Screen Options tab to choose which Dashboard boxes to show.
Drag and Drop – To rearrange the boxes, drag and drop by clicking on the title bar of the selected box and releasing
when you see a gray dotted-line rectangle appear in the location you want to place the box.
Box Controls – Click the title bar of the box to expand or collapse it. Some boxes added by plugins may have
configurable content, and will show a “Configure” link in the title bar if you hover over it.
Content
The boxes on your Dashboard screen are:
At A Glance – Displays a summary of the content on your site and identifies which theme and version of WordPress you
are using.
Activity – Shows the upcoming scheduled posts, recently published posts, and the most recent comments on your posts
and allows you to moderate them.
Quick Draft – Allows you to create a new post and save it as a draft. Also displays links to the 5 most recent draft posts
you’ve started.
WordPress News – Latest news from the official WordPress project, the WordPress Planet, and popular and recent
plugins.
Welcome – Shows links for some of the most common tasks when setting up a new site.
In this episode of our WordPress Tutorial Series we’re going to take a look at
several key components of WordPress. We’ll start by looking at the function of
the WordPress Toolbar, which provides a fantastic navigation mechanism for
the administrator of the website. Hopefully you are said administrator. We’ll get
into various features of the toolbar, how it behaves from the public facing side
vs the administrative side of your site, as well as the key links you’ll be using
very frequently in your day to day work. After this, we’ll have a look at
WordPress Posts as well as WordPress Pages. They are in fact different things,
and we’ll need to know these differences in order to make the best use of each.
Let’s jump in to more WordPress!
WordPress Toolbar
Once you have WordPress installed, you’ll notice that when you log in to your website, a
toolbar is present in the upper portion of your web browser. This toolbar appears both from
the public facing side of your website, as well as the private administrative area of your
WordPress installation. This toolbar is a chameleon of sorts, as it will change it’s
appearance and functionality depending on where you are currently browsing on your
website. It is a fantastic tool for navigating your site, as it provides self explanatory links to
common tasks and resources you’ll need to make use of.
In the far upper left of your browser window from the admin area of WordPress, you’ll see
the familiar WordPress logo. When you hover over that logo, you’ll be provided several
useful options.
• About This link takes you back to the Welcome Page which we covered in the last
episode. You’ll find out information about the newest features, credits, and freedoms.
• WordPress.org This is where you can find the latest and greatest copy of the actual
WordPress application for download.
• Documentation This will take you to the WordPress Codex, a literal treasure trove of
information. Think of it as the ultimate WordPress knowledge base which has
everything you need to learn about WordPress, work with themes, write a plugin, or if
you’re feeling brave, contribute to development of WordPress itself.
• Support Forums This takes you to the official WordPress Forums. With millions of
other WordPress users just like yourself, you are sure to find helpful information and
interactions with other web developers.
• Feedback Want to leave some feedback for the developers? You can do it at this
link.
The WordPress Toolbar House
Right next to the WordPress Logo Navigation you’ll find the icon that looks like a house.
This is the the part of the navigation on the toolbar that you will be using constantly! This
button allows you to quickly toggle between the public and private sections of your
website. When visiting from the public side, it looks like the following.
To the right of this area on the toolbar menu, you’ll see icons that represent Comments, a
new post icon, and a graphic of your website statistics. Let’s review these now.
Comments
Anytime a visitor leave a comment on your blog, this icon will populate with a number. This
is a helpful indicator to let you know that either a comment has been published, or that
there are comments awaiting your moderation.
New Post
Make use of this icon as much as you can! By clicking this icon you get taken to, you
guessed it, the new post editor. This is where you will use your imagination to make the
magic happen.
Stats
One you start getting some visitors to your site, you’ll see this icon start taking different
shapes. These are your visitors, thank them for stopping by.
On the right hand side you’ll see some additional information to help you navigate the
site. When you hover over your user name, you are provided with a few options. You can
view and edit your profile, as well as log out of the current session. Also notice the color
options for the admin area. If you would like to change the appearance of the back end of
your website you can do that here. Chose from Sunrise, Coffee, Ocean, Blue, Midnight,
Light, or Ectoplasm. They all look pretty nice, so go ahead and try a few out yourself to
see how you like them.
As you browse your website while logged in, you’ll notice a new icon appear in the toolbar.
This is only present when you are visiting a single post at a time, not the homepage. This
icon allows you to quickly edit the post you are currently viewing. This is a really fantastic
feature, since unless you have some type of editorial staff checking your work before it
gets published, you’re going to find small tidbits you’d like to change once things are
already live. With this handy icon, you can do just that. It’s actually a good practice to
browse around your latest posts, and just double check that everything is the way you
want it to be. If you do happen to find something that needs a quick correction, just hit that
edit button, fix any typos, and re publish. Awesome!
WordPress Posts
When we think of a WordPress Post, we can think of an update or news item. Any website
that has continually refreshing and new content will usually be using a WordPress Post to
provide this content. Think online news site, web design blog, internet based magazine,
you get the idea. By the very nature of the way WordPress is designed, a new Post gets
displayed front and center on the very top of the home page of the website. It is the latest
update and freshest content. This works very well for most types of websites. New Posts
usually consist of things like a news update, media item like a picture or video, article,
opinion articles, web tutorials and so on. WordPress Posts are displayed from top to
bottom so to speak in a revers chronological order. Almost all the content you come across
on a daily basis is in the form of a new Post.
WordPress Pages
WordPress Pages provide a slightly different means to provide content than your Posts
will. When we think of a Page, it can be more associated with a Permanent type of content,
not an update or news type item. Pages can often provide valuable information about the
site, but are usually not used to serve content in and of themselves. Think Meta.
• Create a Title The first thing you want to do is to assign a title to your post. There
are a few ways to go about this actually. Much has been written about the
importance of choosing and creating appealing titles for your content, and the full
discussion is beyond the scope of this tutorial. When coming back to view all of your
posts in the Dashboard, the only thing that you’ll see in the list of posts is their titles,
so whether you choose the worlds best title or something very simple, just make sure
this is populated. Often times, you’ll circle back around once you have finished the
entire article and rewrite the title to better fit the direction your article took. You can of
course choose any approach you like.
• Add Body Content Once you’ve got a title, you can click into the body area and start
creating your content. There are a million different ways to start creating here. You
might want to simply share a picture and maybe a five word description of it, and
that’s great. On the other side of the coin, maybe you’re ready to hammer out a
twenty five hundred word post replete with images, rich content, snippets, and
assorted links and resources. Go for it! Typically, the more the better (within reason).
• Autosave You’ll be glad that the developers of WordPress have implemented a
fantastic autosave feature into WordPress. As you are creating your post, WordPress
will periodically save the post for you. This saves you one thing you don’t have to
constantly remind yourself to do, and you’ll be safe from various mishaps that can
happen. If you’ve ever lost a large body of work after putting hours and hours into it’s
creation, you’ll know it is beyond disheartening. Fear not, you’re posts will be safe in
WordPress.
• Miscellaneous Finally, there are options to increase indent, decrease indent, undo,
redo, quote, and more.
Custom Layouts
In the Add New Post page, there are many more widgets for you to be aware of and make
use of beyond the Publish widget. Some of the other areas include Format, Categories,
Tags, Featured Image, Revisions, Excerpt, and more. You can determine if you would like
to display these or not via the Screen Options tab at the very top of the page. In addition to
this, if you hover over any widget with your mouse, you’ll notice you are provided with the
four way arrow indicating that you can drag and drop the widget to any location you like.
This is very helpful to customize your workflow in order to make things as smooth and fast
as possible when creating new content.
WordPress Tags
Tags are also very useful for organizing your Posts. In general, tags are used to assign
more granular organization to your posts than you may have with categories. You’ll
typically always have more tags than categories in your WordPress site. These tags
provide a more loose association of your Posts, yet they are really powerful for the overall
schema of the site. They are also excellent in helping the search engines to crawl
information in your posts and relate them to other posts. Tags follow a Many to
Many relationship pattern which we described in a Laravel Tutorial earlier. This means that
a Blog Post can have one or more tags. Each tag can also in turn belong to one or more
Blog Posts. WordPress has its own implementation of the many to many relationship
pattern, and it works like a charm.
Managing Categories and Tags in WordPress
By navigating
to Posts->Categories in the WordPress Dashboard, you’ll be able to create and name
new categories as well as make any edits to existing categories that may be needed. The
first field you want to fill out when creating a category is the name. This is how it will
appear on your site, and depending on the theme in use, will be displayed with each and
every post in that particular category. For example, if you have a Web Development
category like we do here at vegibit, if you click on that category name in the public facing
side of the site, WordPress will display all articles in that category. Next up is the slug, a
great descriptor if there was one. The slug is always lower case and hyphenated in the url
of your site. You’ll want to use pretty urls if you’d like to have your Posts display in the
format of http://coolsite.com/this-is-a-slug. If you like, you can create Parent Child
relationships of your categories. Truthfully, unless you are running a rather large site, you
likely won’t need to implement this. Lastly, you can provide a description of the category. In
addition to this method of category creation, you can just as easily use the +Add New
Category link from the Add New Post page of WordPress when you are creating the post.
Both methods will work just fine.
Quick Edit of Categories and Tags
Once you have a few posts created in your site, you’ll be getting a better feel for how
categories and tags are acting as the glue that hold things together and organize your
data. What happens if you feel that things are not so well organized after all? Maybe a
certain article would fit better in a different category, or you want to add 3 additional tags to
a different post that would benefit the organization. You can do this very quickly by simply
visiting Posts->All Posts and then selecting Quick Edit from one of your entries. Then,
you can simply check and uncheck the categories that apply, in addition to adding or
removing tags that may be appropriate for the article. Once you’re done with your update,
just click Update, and you’re done. Very easy!
Parent Child vs Free Flowing Text
Like we mentioned earlier, your categories can follow a parent / child relationship and are
typically managed within WordPress by using checkboxes. Tags on the other hand are
based on free flowing text. You can type out our tags as needed and click add. Once you
have a substantial number of posts in your website, the tags widget will now start
performing and auto lookup and auto suggest tags based on tags that may already match
in the database. It’s quite slick, and works in a similar way to the Google Suggest feature
when you start to type a search query into the form of Google.
• URL This is the destination to the URL you would like to link to. In this case, we
provide our link of http://wordpress.org
• Title It may seem trivial, but this field is actually very important to fill out. When a
user hovers over a link in your document, they will receive a dynamically generated
pop up with the text specified by this field. This gives an indication of where the link
points to before the user actually clicks it.
• New Window? The checkbox gives you the option to choose if the link will be
opened in the same window, or a new browser window.
• Search If you would like to link to existing content on your website, you can do that
by typing in the search box to find the post you are looking for. It makes sense to
have internal linking as well for both navigation benefit and to help search engines
find all of your relevant posts.
• Submit When you are satisfied that you have added all of the needed attributes to
your link, hit Add Link.
Our result in the actual code of the site is <a title=”WordPress Open Source CMS”
href=”http://wordpress.org/” >WordPress.org</a>. You can see that it’s quicker and
easier to simply use the wizard rather than having to type out all of the actual code, though
you really should know how to create html links by hand if needed!
What we did here is once we had the cursor located where we wanted the image, we click
the Add Media button at the top of the Add New Post Window and we were given the
chose to Upload Files or choose from our existing Media Library. Now what happens is,
any time you upload a file from your computer, it gets added to your Media Library so that
you can reuse images as you see fit. There may be cases where one image might fit the
requirements of several sections of different articles and there is nothing stopping you from
using the image in this way if you like.
The second portion of this is that you need to fill in some
details about the image in the right hand pane. In fact to your right, you can see the
screenshot of what this will look like when you need to add your image. Note all of the
fields you have the option of filling in. It is a best practice to provide all of these fields if you
can. We can see we have an URL, Title, Caption, Alt Text, Description, Alignment, Link To,
and Size fields. Let’s review them.
• URL This is the address of where the image itself lives. Most times this will point to a
sub folder within your wp-content folder on the same domain. You can also use an
external site to host the image, though in most cases you’re not going to want to do
that.
• Title Again, the title field may seem trivial – but it is the details that matter, both to
your users and the search engines. Place some worthwhile descriptive text in this
field.
• Alt Text There may be times when a visitor can’t download the image to view in their
browser due to poor internet connection or some other cause. In that case, you want
to provide some type of textual indication of what should be in the space of where the
image is. Fill in this text to provide that option.
• Description This is another field that is one of those attention to details things that
you should provide.
• Alignment This will drive you batty until you get the hang of working with text and
images together in html. Sometimes you’ll want text to flow around the right side of
an image, others times on the left. Still in other instances, you may want the image to
take up the whole width of the article with no text. You’ll need to practice these
alignment options and be aware of your image sizes when working with your layout.
Practice makes perfect in this case.
• Size You can insert the full size image, or various reduced sizes as you see fit.
You can get much more fancy with images than what we’ve covered here, but images are
slippery little suckers, especially when intertwined with text and html. Stick to the basics,
get your image sizes and alignments right, and you’ll be a happy camper.
Awesome!
Another great feature of image galleries in WordPress is that you can preview and edit
them right in the visual editor. You’re going to want to click the Preview button from within
the Publish Widget to actually view the gallery in the browser. This is the most accurate
way to get a look at how things are doing to display once the article goes live. Let’s images
however that we want to change a caption, change the linking location, or simply add or
remove an image from the gallery. How can we do that? Well, if you go to the visual editor
and hover over the gallery in question, you’ll get the option of either deleting the gallery all
together, or editing. We’ll choose editing, and it looks like so.
In the window above, you can make any modifications you’ll need to get the design to
where you want it to be. This is a simplistic example of using galleries, but you can
experiment with all kinds of fancy approaches to spice up your gallery. They do add a nice
touch to your content.
The WordPress Links and Images Conclusion
You’re going to get more bang for your content buck if you make it a priority to be
awesome at using links and images in your WordPress Posts. After this episode, you now
know how to create links with ease. Whether you’re linking to an external source, or setting
up some nice internal links, you’re a link building pro with WordPress. You also have the
skills you need to add some fresh images to spice up your content. If you’re feeling
adventurous, you might even put together a sweet image gallery for your next WordPress
Blog Post.
Twitter
We’ll use this url https://twitter.com/vegibit/status/511528479276269568
Follow
vegibit @vegibit
The Art of Creating a WordPress Post http://wp.me/p3iC3e-35E
10:54 AM - 15 Sep 2014
11 Retweet
11 like
Instagram
This is our url for instagram http://instagram.com/p/s8ZNZQRMTp/
Photo Credit: http://instagram.com/estherleclerc
Imgur
We’ll use this url http://imgur.com/gallery/mQCle5N
Source
So we can see that by using oEmbed with WordPress, it is possible to easily add
Very Slick!
rich media to your content to great effect.
• Status The status can be toggled between Draft, Pending Review, or Published. For
a one person operation, these will always be either Draft or Published. If you do have
multiple writers for your website, you can make use of the Pending Review option in
order to have an editorial chief review any pending Posts.
• Visibility This provides a few ways to change how the content in your Post is
accessed. By default, it is set to Public, and when the status is Published, any new
Posts will get pushed to the top of your homepage. You can also Sticky the post. You
surely are familiar with the concept of Stick Posts. Sticky Posts are the ability to pin a
post to the top of a section of your website regardless of new Posts being introduced
into the stream. Twitter now also implements a sticky feature, and if you visit any
popular discussion forums on the internet, you’ll also be familiar with the idea of
making a topic or post Sticky. WordPress Posts can also be Private or Password
Protected. Maybe you have a site where you only want to share sensitive information
with users that should be authorized to view said content. In this case simply assign
a password to the post and have the user provide credentials.
• Publish By default, this is set to immediately. This means as soon as you click the
Publish button, your post will go live on the site. If you would like to schedule the post
to go live at a later time, this is the area you can do that in.
• Publicize Not included by default in the WordPress base install, but a part of the
popular WordPress JetPack plugin is the Publicize feature. This great tool allows you
to link your social profiles to your WordPress account. This tool will monitor for new
posts from your website, and when one goes live, the new post will be automatically
distributed across any social networks you have connected. Most users will want to
add Twitter, Facebook, and Google+ however you can also include Tumblr, LinkedIn
and Path if you like.
• Standard The most commonly used format for creating your WordPress Posts.
• Aside The aside format is more of a status update, similar to something you might
find on Twitter or Google Plus.
• Image Use this is the focus of your post is largely on an image.
• Video Likewise for focusing on a video as the main focal point of your post.
• Quote To create a post that is a quote, you can use this format type.
• Link Lastly, if you simply want to share a link with your readers, you can use this
post format type.
Creating a WordPress Page
We mentioned earlier in this WordPress Tutorial Series what the difference is between
WordPress Posts and WordPress Pages. We mentioned that WordPress Posts are going
to be the primary means of creating new content for your website. WordPress posts will
always get placed in the very top most position of your front page in a reverse
chronological order. As such, we have spent a lot of time reviewing how we can create,
update, and edit posts for our WordPress Powered website. Let’s now take a quick look at
WordPress Pages, since they serve a useful purpose as well.
Used for Static Content
The perfect use for WordPress pages is something like an About page. For example, for
VegiBit, we have an about page that lists basic information about the website. It would
make sense for your website to include an about page as well. There are several things
you can include such as:
• General Information For general information you want to include a good overview
for your new visitors that are curious about the topics covered.
• Social Accounts Does your website have one or many social accounts? The about
page is a great place to include them so your readers can connect with you.
• Advertising If you offer advertising, the about page is also a great place to provide a
means to purchase ads.
Chapter 6: Laravel
Install Laravel on Windows
This is going to assume we are starting from scratch using a fresh install of
WAMP 2.4 on Windows. In doing this myself, I ran into a few gotchas so this
post will document those hiccups and get you running with Laravel right away.
Update: We now also have a guide to Install Laravel Homestead on Windows if
you prefer a Virtual Machine environment! So read on if you’d like to install right
on the local machine with WAMP, or follow the link above if you’re ready for
Laravel Homestead.
Install Wamp
Start by getting a nice fresh copy of wamp over at http://www.wampserver.com/en/
Install Composer
Now we can install Composer. This is great, let’s go ahead and do that by
visiting http://getcomposer.org/ and download the windows installer now. Once the installer
is downloaded, go ahead and doubleclick the file to begin installing composer on your
Windows machine.
Install Laravel
Now you are excited, you are ready to rock with Laravel. We got Wamp. Check. We got
Composer. Check. We got Game. Check.
Let’s run the command: composer create-project laravel/laravel blog --prefer-dist
in the www root directory of WAMP. I can’t wait to see this in action! Whoops, I don’t think
we were supposed to see this:
Result: [RuntimeException] You must enable the openssl extension to download files
via https
Ok, fair enough. Let’s go ahead and enable the PHP extension in WAMP. It’s so easy after
all, all we have to do is click the WAMP Icon in the task tray, choose PHP->PHP Extensions-
>php_openssl! Now we can restart all services and DO THIS.
Run the command: composer create-project laravel/laravel blog --prefer-dist
Result: [RuntimeException] You must enable the openssl extension to download files
via https
WHAT THE …?! Still getting errors and no install. But it said to enable open SSL, and my
extension has a nice checkmark next to it in WAMP, WHAT IS THE DAMN PROBLEM?!
Turns out, if you enable open SSL through the wamp UI, it doesn’t actually turn it on. After
perusing stack overflow, I find that you also have to navigate to
your C:wampbinphpphp5.4.16 folder and uncomment the extension=php_openssl.dll in the
php.ini file.
Ok let’s remove the ; to uncomment openssl, restart all services, and DO THIS. No this
time, I really mean DO THIS!!
Run the command: composer create-project laravel/laravel blog --prefer-dist
Bingo Bango! – ok, no errors, it’s thinking, oh wow – we’re really downloading some
awesome stuff now!
C:wampwww>composer create-project laravel/laravel blog --prefer-dist
Installing laravel/laravel (v4.1.0)
- Installing laravel/laravel (v4.1.0)
Downloading: 100%
symfony/routing suggests installing symfony/config (For using the all-in-one router or any loader)
symfony/routing suggests installing symfony/yaml (For using the YAML loader)
symfony/routing suggests installing symfony/expression-language (For using expression matching)
symfony/routing suggests installing doctrine/annotations (For using the annotation loader)
symfony/translation suggests installing symfony/config ()
symfony/translation suggests installing symfony/yaml ()
symfony/event-dispatcher suggests installing symfony/dependency-injection ()
symfony/http-kernel suggests installing symfony/class-loader ()
symfony/http-kernel suggests installing symfony/config ()
symfony/http-kernel suggests installing symfony/dependency-injection ()
predis/predis suggests installing ext-phpiredis (Allows faster serialization and deserialization of
the Redis protocol)
predis/predis suggests installing ext-curl (Allows access to Webdis when paired with phpiredis)
phpseclib/phpseclib suggests installing ext-gmp (Install the GMP (GNU Multiple Precision) extension
in order to speed up arbitrary precision integer arithmetic operations.)
phpseclib/phpseclib suggests installing pear-pear/PHP_Compat (Install PHP_Compat to get phpseclib wo
rking on PHP >= 4.3.3.)
patchwork/utf8 suggests installing ext-intl (Use Intl for best performance)
monolog/monolog suggests installing mlehner/gelf-php (Allow sending log messages to a GrayLog2
server)
monolog/monolog suggests installing ext-amqp (Allow sending log messages to an AMQP server (1.0+
required))
monolog/monolog suggests installing ext-mongo (Allow sending log messages to a MongoDB server)
monolog/monolog suggests installing doctrine/couchdb (Allow sending log messages to a CouchDB server)
monolog/monolog suggests installing raven/raven (Allow sending log messages to a Sentry server)
monolog/monolog suggests installing ruflin/elastica (Allow sending log messages to an Elastic Search
server)
monolog/monolog suggests installing aws/aws-sdk-php (Allow sending log messages to AWS services like
DynamoDB)
d11wtq/boris suggests installing ext-readline (*)
d11wtq/boris suggests installing ext-pcntl (*)
d11wtq/boris suggests installing ext-posix (*)
laravel/framework suggests installing doctrine/dbal (Allow renaming columns and dropping SQLite
columns.)
Writing lock file
Generating autoload files
Generating optimized class loader
Application key [H3tKsDs7StT9ZIuDXaUfcXY33XYvPJQJ] set successfully.
C:wampwww>
Blog project built. Awesome. Ok, small setbacks aside – I’m ready to really rock and roll –
let’s create our first route! Per the docs at Laravel, lets add this code to our routes.php file
<?php
Route::get('users', function()
{
return 'Users!';
});
Now, if you hit the /users route in your web browser, you should see Users! displayed as
the response. Great! You’ve just created your first route. Ok, let me try it
Hit it: http://localhost/blog/public/users
Not Found
Crud In Laravel
So if you read Install Laravel on Windows (or a Mac, we like those too!), you’re
probably wondering what comes next. We have this Laravel installation running
and the friendly message letting us know we have arrived is on the screen. We
have untold amounts of power at our fingertips, but it’s a bit confusing as to
where to begin next. Well this post will start getting our hands dirty in putting
Laravel to use as well as implementing Create, Retrieve, Update, and Delete!
Route::get('/', function()
{
$posts = DB::table('posts')->get();
dd($posts);
});
//array (size=1)
// 0 =>
// object(stdClass)[130]
// public 'id' => int 1
// public 'title' => string 'A Cool Title' (length=12)
// public 'body' => string 'With a Nice Body' (length=16)
Awesome! You can see we have retrieved the data which we had previously entered into
the database at the command line. Let’s add some more data to the database with mysql>
insert into posts(title,body) values('Our 2nd Title', 'Our Second Body'); then run
that same query:
<?php
Route::get('/', function()
{
$posts = DB::table('posts')->get();
dd($posts);
});
//array (size=2)
// 0 =>
// object(stdClass)[131]
// public 'id' => int 1
// public 'title' => string 'A Cool Title' (length=12)
// public 'body' => string 'With a Nice Body' (length=16)
// 1 =>
// object(stdClass)[132]
// public 'id' => int 2
// public 'title' => string 'Our 2nd Title' (length=13)
// public 'body' => string 'Our Second Body' (length=15)
Oh yeah! We’re returning both rows with ease. Now the get() method is quite powerful
and returns everything in that table. You will need to be much more granular in your select
statements in the real world. Let’s find a post by id using the find()method:
<?php
Route::get('/', function()
{
$posts = DB::table('posts')->find(1);
dd($posts);
});
Well that was really cool! Let’s get more granular and only access the title of the post that
has id of 1:
<?php
Route::get('/', function()
{
$posts = DB::table('posts')->find(1);
dd($posts->title);
});
// Check it out, you have access to each field within the table
// simply by accessing the property of the object returned
//
// string 'A Cool Title' (length=12)
How about using where clauses? We can do that quite easily like so using
the where()method:
<?php
Route::get('/', function()
{
$posts = DB::table('posts')->where('id', '!=', '1')->get();
dd($posts);
});
Insert (Create)
Let’s go ahead and add a third row to our database but instead of using the mysql console,
we will now use the DB class of Laravel with the insert method!
<?php
Route::get('/', function()
{
$posts = DB::insert('insert into posts (title, body) values(?, ?)', array('Insert from DB
class','How Ya Like Me Now?!'));
dd($posts);
});
Retrieve (Select)
Let’s select that new record just to be sure it took!
<?php
Route::get('/', function()
{
$posts = DB::select('select * from posts where id = ?', array(3));
dd($posts);
});
//array (size=1)
// 0 =>
// object(stdClass)[130]
// public 'id' => int 3
// public 'title' => string 'Insert from DB class' (length=20)
// public 'body' => string 'How Ya Like Me Now?!' (length=20)
Update (Update)
I think we’ll update the body of that same post now:
<?php
Route::get('/', function()
{
$posts = DB::update('update posts set body = "I Like Ya!" where id = ?', array(3));
dd($posts);
});
// int 1
Delete (Delete)
Last up we have the delete method. I bet you can guess what it does
<?php
Route::get('/', function()
{
$posts = DB::delete('delete from posts where id = ?', array(3));
dd($posts);
});
// int 1
And just like that, we have deleted the given post. We haven’t even scratched the surface
with Laravel and this is as they say only the tip of the iceberg. Coming soon will be a dive
into Eloquent for which minds will be blown.
In Laravel, sets that are returned as a result of an eloquent query return a collection.
note:
You can learn all about Laravel Collections over at our lengthy tutorial.
use IlluminateDatabaseSchemaBlueprint;
use IlluminateDatabaseMigrationsMigration;
class CreatePaintersTable extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('painters', function(Blueprint $table)
{
$table->increments('id');
$table->string('username')->unique();
$table->text('bio');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('painters');
}
<?php
// paintings table
use IlluminateDatabaseSchemaBlueprint;
use IlluminateDatabaseMigrationsMigration;
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('paintings', function(Blueprint $table)
{
$table->increments('id');
$table->string('title');
$table->text('body');
$table->integer('painter_id');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('paintings');
}
Ok we have our Eloquent Model created, yes I know it was painful how much we had to
type! Let’s see what that one little line of code buys us by using reflection to inspect our
newly created object!
<?php
Route::get('/', function()
{
$reflection = new ReflectionClass('Painter'); // inspect the methods and constants of any class!
print_r($reflection->getMethods());
});
The above code will output the 164 methods you find at Laravel Eloquent API – This is a
bit overwhelming! But as they say, CALM YOURSELF GRASSHOPPER! We’re only going
to look at a few of them to get us started. Since we already covered how to set up CRUD
In Laravel with the DB class, why don’t we now whip up some CRUD with Eloquent. Since
we’re learning we will use:
<?php
Create
save() We can insert new records into the database a few ways in Eloquent, but my
favorite syntax is here using the save method:
<?php
Route::get('/', function()
{
$painter = new Painter;
$painter->username = 'Leonardo Da Vinci';
$painter->bio = 'Renaissance painter, scientist, inventor, and more. Da Vinci is one of most
famous painters for his iconic Mona Lisa and Last Supper.';
$painter->save();
});
string ‘insert into painters (username, bio, updated_at, created_at) values (?, ?, ?, ?)’
(length=90)
Retrieve (Select)
all() and first() Let’s have a look at our newly created record by selecting data now:
<?php
Route::get('/', function()
{
$painters = Painter::all()->first();
echo $painters->username.'<br>';
echo $painters->bio;
});
Route::get('/', function()
{
$painters = Painter::all()->first();
$painters->username = 'Leonardo Da-Vinci';
$painters->save();
});
Delete
delete With eloquent, deleting a record is super easy. Have a look:
<?php
Route::get('/', function()
{
$painters = Painter::all()->first();
$painters->delete();
});
Relationships in Eloquent
Relationships are a key component in Eloquent but first, we need some more painters!
Let’s add them:
<?php
Route::get('/', function()
{
$painter = new Painter;
$painter->username = 'Leonardo Da Vinci';
$painter->bio = 'Renaissance painter, scientist, inventor, and more. Da Vinci is one of most
famous painters for his iconic Mona Lisa and Last Supper.';
$painter->save();
string ‘insert into painters (username, bio, updated_at, created_at) values (?, ?, ?, ?)’
(length=90)
string ‘insert into painters (username, bio, updated_at, created_at) values (?, ?, ?, ?)’
(length=90)
string ‘insert into painters (username, bio, updated_at, created_at) values (?, ?, ?, ?)’
(length=90)
Great! Now, we know that Painters will likely have created some Paintings. For Brevity, I will
show just one snippet of how we can insert a Painting. Just note that for our purposes
Leonardo Da Vinci is painter_id 2, Vincent Van Gogh is id painter_id 3, and Rembrandt is
id painter_id 4. It is by this very field, painter_id, which is in the paintings table, that
facilitates our relationships. We’ll need to remember this when constructing methods to
select data from our database using relationships!
Sample Painting insert:
<?php
Route::get('/', function()
{
$painter = Painter::find(4);
note:We execute variations on the above code a few times in order to give each Painter at
least 2 Paintings each in the database.
hasMany
A Painter will typically have many Paintings just like an Author may have many Books, or a
Chicken may have many eggs. In Laravel, we can define relationships like this in our
Model like so:
<?php
Here is a great trick to help you remember how this works! Start with the $this keyword,
followed by the class name of the file, followed by the $this method, followed by
the Model passed in. So in this case it would read like: This Painter hasMany
Painting. See how that works?!
belongsTo
The inverse of this is that all Paintings must have been Painted by a Painter. We could
also say that a Painting belongsTo a Painter. Let’s see this model!
<?php
We can use the same trick here! (this|name of class file|name of method|name of model
passed in) So in this case we would have This Painting belongsTo Painter.
Nice work!
Route::get('/', function()
{
$painter = Painter::whereUsername('Leonardo Da Vinci')->first();
foreach($painter->paintings as $painting){
echo $painting->title.'<br>';
echo $painting->body.'<br><br>';
}
});
Route::get('/', function()
{
$painting = Painting::whereTitle('The Potato Eaters')->first();
echo Painter::find($painting->painter_id)->username;
});
string ‘select * from paintings where title = ? limit 1′ (length=51)
string ‘select * from painters where id = ? limit 1′ (length=47)
Vincent Van Gogh
Of Course! Vincent Van Gogh is the Painter that painted ‘The Potato Eaters’! The above
code was the long hand way to do this. You see, when we create both relationships, we
can combine the models to reach any field on either table by going through it! Since we
created an instance of the Painting model in $painting, we can now go through
the Painter model to reach any field in that table. How? Like this:
<?php
Route::get('/', function()
{
$painting = Painting::whereTitle('The Potato Eaters')->first();
echo $painting->painter->username.'<br>';
echo $painting->painter->bio;
});
Route::get('/', function()
{
$paintings = Painting::all();
foreach($paintings as $painting){
echo $painting->painter->username;
echo ' painted the ';
echo $painting->title;
}
});
Route::get('/', function()
{
$paintings = Painting::with('painter')->get();
foreach($paintings as $painting){
echo $painting->painter->username;
echo ' painted the ';
echo $painting->title;
echo '<br>';
}
});
JSON in Laravel
If you know the name Douglas Crockford, you know JSON. Mr Crockford is
a Chuck Norris of sorts in the Javascript world and created the JSON
standard. It stands for JavaScript Object Notation and it provides a great way to
share data between languages and applications. Douglas I’m sure is proud of
his baby, and we can thank him for declaring himself a standards body and
bringing JSON into existence. Let’s learn a little more about JSON in Laravel!
Why JSON?
When dealing with data transfer, we need a convenient method of markup. XML was the
first way to accomplish this, but now we are seeing a major uptake of
JSON. Why? Because JSON is very easy to read and convenient for storing arrays and
objects with values as strings.
AJAX is a popular method of using JSON. Let’s say you make an AJAX hit on your
application from the front end, often times the server side will respond with JSON as that
data can now be easily parsed and integrated into the Javascript front end. It’s quite
magical in fact! If you have ever used the Twitter API, you will also notice that JSON is
their method of data exchange.
In PHP we have some nifty functions named json_encode() and json_decode() and
Laravel makes great use of these. Let’s now take a look at some JSON!
If you are using Firefox you may need to install an add-on like JSONview to make the
note:
JSON output pretty in the browser.
Remembering our Laravel Eloquent ORM Tutorial, let’s take an example Database query,
and return it’s output to the browser:
<?php
Route::get('/', function()
{
$paintings = Painting::all();
return $paintings;
});
{
"id": 1,
"title": "Mona Lisa",
"body": "The Mona Lisa is a half-length portrait of a woman by the Italian artist Leonardo da
Vinci, which has been acclaimed as "the best known, the most visited, the most written about, the
most sung about, the most
commissioned as part of a scheme of renovations to the church and its convent buildings by Leonardos
patron Ludovico Sforza, Duke of Milan. ",
"painter_id": 2,
"created_at": "2014-01-24 19:55:46",
"updated_at": "2014-01-24 19:55:46"
},
{
"id": 3,
"title": "The Starry Night",
"body": "Starry Night is a painting by the Dutch post-impressionist artist Vincent van Gogh.
Painted in June 1889, it depicts the view outside of his sanitarium room window at Saint-Rémy-de-
Provence at night",
"painter_id": 3,
"created_at": "2014-01-24 19:57:39",
"updated_at": "2014-01-24 19:57:39"
},
{
"id": 4,
"title": "The Potato Eaters",
"body": "The Potato Eaters is a painting by the Dutch painter Vincent van Gogh that he
painted in April 1885 while in Nuenen, Netherlands. It is in the Van Gogh Museum in Amsterdam.",
"painter_id": 3,
"created_at": "2014-01-24 19:58:31",
"updated_at": "2014-01-24 19:58:31"
},
{
"id": 5,
"title": "The Night Watch",
"body": "The Night Watch or The Shooting Company of Frans Banning Cocq is the common name of
one of the most famous works by Dutch painter Rembrandt van Rijn.",
"painter_id": 4,
"created_at": "2014-01-24 19:59:44",
"updated_at": "2014-01-24 19:59:44"
},
{
"id": 6,
"title": "The Storm on the Sea of Galilee",
"body": "The Storm on the Sea of Galilee is a painting from 1633 by the Dutch Golden Age
painter Rembrandt van Rijn that was in the Isabella Stewart Gardner Museum of Boston, Massachusetts,
United States, prior to
I like to strictly use single quotes in my Javascript and double quotes in JSON, that way I
don’t get mixed up.
• Double
• Float
• String
• Boolean
• Array
• Object
• Null
[“paintbrush”,”canvas”,”apron”]
<?php
$tools = '["paintbrush","canvas","apron"]';
$tools = json_decode($tools);
echo $tools[0]; // paintbrush
echo $tools[1]; // canvas
echo $tools[2]; // apron
This might be a little confusing so if you would rather have json_decode() create an array
for you instead of stdClass, just pass in true as the second parameter to the function like
so:
<?php
echo $osi['physical'];
echo $osi['data link'];
echo $osi['network'];
echo $osi['transport'];
echo $osi['session'];
echo $osi['presentation'];
echo $osi['application'];
Having a good knowledge of JSON will keep us running mean and lean in our applications,
and it will also help us when working with Composer since it uses JSON.
Inversion of Control
First up, just a little bit about Inversion of Control, in the generic sense.
Wikepedia provides us this explanation:
In software engineering, inversion of control (IoC) is a programming technique, expressed here in
terms of object-oriented programming, in which object coupling is bound at run time by an assembler
object and is typically not known at compile time using static analysis.
In traditional programming, the flow of the business logic is determined by objects that are statically
assigned to one another. With inversion of control, the flow depends on the object graph that is
instantiated by the assembler. Such a dynamic flow is made possible by object interactions being
defined through abstractions. The binding process is achieved through dependency injection,
although some argue that the use of a service locator also provides inversion of control.
What chu talkin bout Willis? Well, that is a lot of verbiage to basically say, with good
software engineering, we are going to make your life easier. How so you say? Let’s
examine.
A container is just that, something that can hold things. In Laravel, the $app object is your
container. So it stands to reason that this $app you speak of contains things, and if fact, it
does. If you were to run this code
<?php
Route::get('/', function()
{
$app = app();
print_r($app);
});
You would see an ungodly amount of information dumped to the browser. The main thing
to notice however is that it is an Object of IlluminateFoundationApplication. The
illuminate namespace contains all components of the Laravel framework. It’s an apropos
name in as much as Laravel is bringing software design features from other enterprise
languages into the world of PHP. Now,
the Application class extends the Container class. It is from the Container class that
wizardry emanates. Think of learning Laravel, not so much as an exercise in coding chops,
but rather an expansion of your mind. It provides a new and different way of looking at
problems and how to solve them with ingenious organization. In fact, Laravel challenges
the very definition of a framework. At least that is how I think of it.
The Container class implements the ArrayAccess interface. What this means is that you
have flexibility when accessing your data. You can use what feels comfortable to you. For
example you could use both of the following syntax versions with the same result:
<?php
$foo->bar = "baz";
$foo['bar'] = "baz";
Nifty!
Dependency Injection
Dependency Injection is great but it can become a pain to implement if you have to
continuously instantiate and pass in dependencies but with the IoC container, we don’t
have to worry about it.
So how does this all work in code? Well let’s whip up a few classes and see it in action.
We’ll add a Car, Tire, and Engine class. We know the App class extends the Container,
so we have access to it’s methods. Let’s go ahead and bind our Car class to
the Container.
<?php
App::bind('Car', function()
{
return new Car;
});
Route::get('/', function()
{
dd(App::make('Car')); // resolve it
});
// object(Car)[146]
Excellent – When we run make by way of App, we can see our Car object comes into being.
Let’s consider that a Car depends on the Tire and Engine classes. How can we do this?
<?php
class Car {
protected $tire;
protected $engine;
public function __construct(Tire $tire, Engine $engine) {
$this->tire = $tire;
$this->engine = $engine;
}
}
class Tire {}
class Engine {}
App::bind('Car', function()
{
return new Car(new Tire, new Engine);
});
Route::get('/', function()
{
dd(App::make('Car')); // resolve it
});
// object(Car)[145]
// protected 'tire' =>
// object(Tire)[143]
// protected 'engine' =>
// object(Engine)[150]
So here we bind the Car to the App Container and since we specified it’s dependencies by
passing in a Tire and Engine to it, we’ll get a shiny new object with all needed
dependencies having been passed in.
Ok let’s change it up a little:
<?php
class Car {
protected $tire;
protected $engine;
public function __construct(Tire $tire, Engine $engine) {
$this->tire = $tire;
$this->engine = $engine;
}
}
class Tire {}
class Engine {}
Route::get('/', function()
{
dd(App::make('Car')); // resolve it
});
// object(Car)[152]
// protected 'tire' =>
// object(Tire)[153]
// protected 'engine' =>
// object(Engine)[154]
Notice our binding is gone. Not only is the binding gone, but the dependencies that we
had manually created and passed in are gone. What happens now? Yes my man, you still
get the object you need, Dependencies included! What the?!
In all of it’s goodness, Laravel will take the following actions for you:
• Did the user specifically create a binding for Car? (use it if so)
• What if the programmer didn’t specify one? Then reflect into Car to determine any
dependencies.
• Resolve any dependencies needed by Car (Tire and Engine).
• Create the new instance for you, including any dependencies, Free of charge!
Wow. I wish I would have thought of that! If I had a glyphicon for a jaw drop, I would add it.
In light of this we’ll go for a big thumbs up Thanks to Taylor Otwell and his team of
superstars such as Dayle Rees, Shawn McCool, Jeffrey Way, Jason Lewis, Ben Corlett,
Franz Liedke, Dries Vints, Mior Muhammad Zaki, and Phil Sturgeon for making all this cool
stuff!
Dependencies of Dependencies
So let’s take this concept just a little further. We know our Car has dependencies of
a Tire and an Engine. What happens if the Tire or Engine have their own dependencies?
Let’s say our Tire has a Bridgestone dependency, and the Engine has
a Turbo dependency. We still just want to make a Car, will our IoC take care of all of this for
us?
Let’s see!
<?php
class Car {
protected $tire;
protected $engine;
public function __construct(Tire $tire, Engine $engine) {
$this->tire = $tire;
$this->engine = $engine;
}
}
class Tire {
protected $bridgestone;
public function __construct(Bridgestone $bridgestone) {
$this->bridgestone = $bridgestone;
}
}
class Engine {
protected $turbo;
public function __construct(Turbo $turbo) {
$this->turbo = $turbo;
}
}
class Bridgestone {
public $tread;
public function __construct(){
$this->tread = 'Performance';
}
}
class Turbo {
public $stage;
public function __construct(){
$this->stage = 2;
}
}
Route::get('/', function()
{
dd(App::make('Car')); // resolve it
});
// object(Car)[154]
// protected 'tire' =>
// object(Tire)[155]
// protected 'bridgestone' =>
// object(Bridgestone)[158]
// public 'tread' => string 'Performance' (length=11)
// protected 'engine' =>
// object(Engine)[157]
// protected 'turbo' =>
// object(Turbo)[160]
// public 'stage' => int 2
Double thumbs up! The Container was able to work some real magic in
Holy Macaroni!
resolving whatever the Car needed.
In a nutshell, this is what the IoC container is for – it makes the task of setting up
dependency injection much easier. Understanding the IoC Container is going to be very
helpful once we start using the Laravel Repository Pattern to facilitate more readable and
maintainable code.
interface CarInterface {
public function start();
public function gas();
public function brake();
}
Awesome! This tells our code that we can have any type of car we want, as long as
it implements a start() gas() and brake() method. This is the API or contract of the
interface.
Route::get('/', function()
{
dd(App::make('CarInterface'));
});
interface CarInterface {
public function start();
public function gas();
public function brake();
}
App::bind('CarInterface', 'Subaru');
Route::get('/', function()
{
$car = App::make('CarInterface');
$car->start();
$car->gas();
$car->brake();
});
// Starts great
// Hit the gas and let the all wheel drive grip those back roads!
// Wow these Brembo brakes are powerful
interface CarInterface {
public function start();
public function gas();
public function brake();
}
App::bind('CarInterface', 'Porche');
Route::get('/', function()
{
$car = App::make('CarInterface');
$car->start();
$car->gas();
$car->brake();
});
// Push button start
// 0 to 60 in 3.7 seconds!
// Brakes? Who needs brakes?
Whatever is bound to the interface is the class you will get access to.
This concludes our first series on the great Laravel Framework. There are many resources
available to you in your Laravel journey, one being the source itself http://laravel.com/ and
also the latest happenings, news, podcasts, and tutorials for Laravel at Laravel News, do
be sure to give them a visit!
Cool!We can use the same trick we used in our Laravel Eloquent Tutorial. If you recall we
can Start with the $this keyword, followed by the class name of the file, followed by the
$this method, followed by the Model passed in. So in these two cases we’ll have This
Blogpost belongsToMany Tag and This Tag belongsToMany Blogpost. I love this
stuff
For brevity, we have already seeded the database with some blogposts, tags, and also
relationships in our blogpost_tag pivot table. Feel free to add some blogposts and tags to
your database if you are following along so you can test it for yourself.
We’re going to focus on retrieving data to start. Right now, our tags table and blogpost_tag
pivot table look like this:
mysql> select * from tags;
+----+-----------+---------------------+---------------------+
| id | name | created_at | updated_at |
+----+-----------+---------------------+---------------------+
| 1 | laravel | 0000-00-00 00:00:00 | 0000-00-00 00:00:00 |
| 2 | bootstrap | 0000-00-00 00:00:00 | 0000-00-00 00:00:00 |
| 3 | windows | 0000-00-00 00:00:00 | 0000-00-00 00:00:00 |
+----+-----------+---------------------+---------------------+
This is pretty cool. You can see we have 3 tags in our tags table, namely laravel,
bootstrap, and windows. In our blogpost_id pivot table we have the relationships that exist
between those tags, and the blogposts in the database. Going line by line we can see that:
Route::get('/', function()
{
$tag = Tag::find(1);
return $tag->blogposts;
});
{
"id": 3,
"title": "Laravel Eloquent ORM Tutorial",
"body": "Eloquent is the very powerful and expressive ORM or Object Relational Mapper in
Laravel. If you know how to work with Objects in PHP, then you know how to use Eloquent! ",
"created_at": "0000-00-00 00:00:00",
"updated_at": "0000-00-00 00:00:00",
"pivot": {
"tag_id": 1,
"blogpost_id": 3
}
},
{
"id": 4,
"title": "Install Laravel on Windows",
"body": "This is going to assume we are starting from scratch using a fresh install of WAMP
2.4 on Windows.",
"created_at": "0000-00-00 00:00:00",
"updated_at": "0000-00-00 00:00:00",
"pivot": {
"tag_id": 1,
"blogpost_id": 4
}
}
Now we’ll do the same for tag_id 2 (bootstrap) and tag_id 3 (windows)
<?php
Route::get('/', function()
{
$tag = Tag::find(2);
return $tag->blogposts;
});
{
"id": 1,
"title": "You Should Use Twitter Bootstrap!",
"body": "If you are a design savvy person, you may have noticed that Vegibit uses the Twitter
Bootstrap Framework. I freaking love this framework, and you should too, or rather if you’re
unfamiliar, you will love it by the time you finish reading this article.",
"created_at": "0000-00-00 00:00:00",
"updated_at": "0000-00-00 00:00:00",
"pivot": {
"tag_id": 2,
"blogpost_id": 1
}
},
{
"id": 2,
"title": "Twitter Bootstrap Modal Tutorial",
"body": "Modals are a fun way to add interactivity to your website. When a user needs to make
a choice, or confirm an action, the classic jquery modal popup makes perfect sense.",
"created_at": "0000-00-00 00:00:00",
"updated_at": "0000-00-00 00:00:00",
"pivot": {
"tag_id": 2,
"blogpost_id": 2
}
}
<?php
Route::get('/', function()
{
$tag = Tag::find(3);
return $tag->blogposts;
});
{
"id": 4,
"title": "Install Laravel on Windows",
"body": "This is going to assume we are starting from scratch using a fresh install of WAMP
2.4 on Windows.",
"created_at": "0000-00-00 00:00:00",
"updated_at": "0000-00-00 00:00:00",
"pivot": {
"tag_id": 3,
"blogpost_id": 4
}
},
{
"id": 5,
"title": "Install and Configure Windows Server 2012 with Windows Powershell",
"body": "Windows PowerShell is an amazingly powerful tool to help you with common windows
administrative tasks. If you are comfortable with one of the myriad of scripting languages available
today, Powershell will be easy for you to learn while also providing the benefits of command line
administration. ",
"created_at": "0000-00-00 00:00:00",
"updated_at": "0000-00-00 00:00:00",
"pivot": {
"tag_id": 3,
"blogpost_id": 5
}
}
We can also now do this in reverse! Let’s tell the database to Give us all tags that have a
blogpost_id of 4
<?php
Route::get('/', function()
{
$blogpost = Blogpost::find(4);
return $blogpost->tags;
});
{
"id": 1,
"name": "laravel",
"created_at": "0000-00-00 00:00:00",
"updated_at": "0000-00-00 00:00:00",
"pivot": {
"blogpost_id": 4,
"tag_id": 1
}
},
{
"id": 3,
"name": "windows",
"created_at": "0000-00-00 00:00:00",
"updated_at": "0000-00-00 00:00:00",
"pivot": {
"blogpost_id": 4,
"tag_id": 3
}
}
Here we can see that Laravel correctly brings back tags of laravel and windows, since
they are both associated with the blogpost_id of 4 (Install Laravel on Windows).
Route::get('/', function()
{
$tag = new Tag(array('name' => 'wamp'));
Blogpost::find(4)->tags()->save($tag);
return $blogpost->tags;
});
{
"id": 1,
"name": "laravel",
"created_at": "0000-00-00 00:00:00",
"updated_at": "0000-00-00 00:00:00",
"pivot": {
"blogpost_id": 4,
"tag_id": 1
}
},
{
"id": 3,
"name": "windows",
"created_at": "0000-00-00 00:00:00",
"updated_at": "0000-00-00 00:00:00",
"pivot": {
"blogpost_id": 4,
"tag_id": 3
}
},
{
"id": 4,
"name": "wamp",
"created_at": "2014-02-04 17:32:36",
"updated_at": "2014-02-04 17:32:36",
"pivot": {
"blogpost_id": 4,
"tag_id": 4
}
}
Wow!This is why people are going bananas over Laravel. Just read the syntax, it makes so
much sense!Create a new tag, find the blogpost we want to assign it to, and save it. Done.
Now, let’s say you refreshed the page one too many times and it creates the wamp tag
twice. (Yes, I did this ) We don’t need the same tag assigned to a blogpost twice, so
let’s remove one of them with the detach method.
[
{
"id": 1,
"name": "laravel",
"created_at": "0000-00-00 00:00:00",
"updated_at": "0000-00-00 00:00:00",
"pivot": {
"blogpost_id": 4,
"tag_id": 1
}
},
{
"id": 3,
"name": "windows",
"created_at": "0000-00-00 00:00:00",
"updated_at": "0000-00-00 00:00:00",
"pivot": {
"blogpost_id": 4,
"tag_id": 3
}
},
{
"id": 4,
"name": "wamp",
"created_at": "2014-02-04 17:32:36",
"updated_at": "2014-02-04 17:32:36",
"pivot": {
"blogpost_id": 4,
"tag_id": 4
}
},
{
"id": 5,
"name": "wamp",
"created_at": "2014-02-04 17:32:54",
"updated_at": "2014-02-04 17:32:54",
"pivot": {
"blogpost_id": 4,
"tag_id": 5
}
}
<?php
Route::get('/', function()
{
$blogpost = Blogpost::find(4);
$blogpost->tags()->detach(5);
return $blogpost->tags;
});
And just like that, we have removed the second instance of wamp from Install Laravel on
Windows.
[
{
"id": 1,
"name": "laravel",
"created_at": "0000-00-00 00:00:00",
"updated_at": "0000-00-00 00:00:00",
"pivot": {
"blogpost_id": 4,
"tag_id": 1
}
},
{
"id": 3,
"name": "windows",
"created_at": "0000-00-00 00:00:00",
"updated_at": "0000-00-00 00:00:00",
"pivot": {
"blogpost_id": 4,
"tag_id": 3
}
},
{
"id": 4,
"name": "wamp",
"created_at": "2014-02-04 17:32:36",
"updated_at": "2014-02-04 17:32:36",
"pivot": {
"blogpost_id": 4,
"tag_id": 4
}
}
We can also use the attach method to assign a tag to a blogpost like this:
<?php
Route::get('/', function()
{
$blogpost = Blogpost::find(4);
$blogpost->tags()->attach(2);
return $blogpost->tags;
});
Well will you take a look at that! Look at our bootstrap tag, now happily attached to this
blogpost.
[
{
"id": 1,
"name": "laravel",
"created_at": "0000-00-00 00:00:00",
"updated_at": "0000-00-00 00:00:00",
"pivot": {
"blogpost_id": 4,
"tag_id": 1
}
},
{
"id": 2,
"name": "bootstrap",
"created_at": "0000-00-00 00:00:00",
"updated_at": "0000-00-00 00:00:00",
"pivot": {
"blogpost_id": 4,
"tag_id": 2
}
},
{
"id": 3,
"name": "windows",
"created_at": "0000-00-00 00:00:00",
"updated_at": "0000-00-00 00:00:00",
"pivot": {
"blogpost_id": 4,
"tag_id": 3
}
},
{
"id": 4,
"name": "wamp",
"created_at": "2014-02-04 17:32:36",
"updated_at": "2014-02-04 17:32:36",
"pivot": {
"blogpost_id": 4,
"tag_id": 4
}
}
Route::get('/', function()
{
$blogpost = Blogpost::find(4);
$blogpost->tags()->sync(array(1,2,3,4));
return $blogpost->tags;
});
// This blogpost now has all tags associated with it
Route::get('/', function()
{
$blogpost = Blogpost::find(4);
$blogpost->tags()->sync(array(1));
return $blogpost->tags;
});
// The same blogpost now has only tag with id of 1 assigned to it
Young Laraveler, do you believe in fate? Why not? Because you are not in
control? You are here because you know something. It is not easy for you to
explain, however you feel it. You have felt it since you began programming in
PHP. There is something wrong with PHP and it’s frameworks. You are not
sure what it is, but it is there. Like a memory leak you can not find, driving you
mad. This feeling has brought you to Laravel. Do you know what I’m talking
about?
The Facade?
Do you want to know what it is?
Facades are everywhere, they are all around our code. Even now in this very simple
snippet
<?php
Route::get('/', function(){});
// what is real
$app['router']->get('/', function()
{
return 'You take the red pill and you stay in Wonderland and I show you how deep the rabbit-hole
goes.';
});
With a nod to the Matrix, we’ll investigate Facades. In the matrix the system was the
enemy, however in Laravel, Facades are actually your friend. You’ll notice that a lot of the
coding done in Laravel looks like it is calling static methods to give it’s nice and short
syntax. The truth is, that is not what is happening, Laravel is making use of it’s Facade
class to give you this great syntax, while also at the same time, employing the IoC
Container to instantiate objects and any dependencies for you to use. So you can see, the
short syntax acts almost like a macro, or shortcut. While they look like static classes, they
actually are not. What this does is decouple your code from the implementation.
Format of a Facade
Most times in Laravel, you will see something similar to, or following the format
of Component::verb(). The component would be something like Route or DB, and the verb
would be something describing the action taken on that component like get() or select().
returns the string router, so that is what gets resolved and made available to us.
The full Route Facade looks like this
<?php namespace IlluminateSupportFacades;
/**
* @see IlluminateRoutingRouter
*/
class Route extends Facade {
/**
* Determine if the current route matches a given name.
*
* @param string $name
* @return bool
*/
public static function is($name)
{
return static::$app['router']->currentRouteNamed($name);
}
/**
* Determine if the current route uses a given controller action.
*
* @param string $action
* @return bool
*/
public static function uses($action)
{
return static::$app['router']->currentRouteUses($action);
}
/**
* Get the registered name of the component.
*
* @return string
*/
protected static function getFacadeAccessor() { return 'router'; }
}
__callStatic($method, $args)
In the parent Facade class, this method gets called when a static method that does not
exist on a class is called. So when you call Route::get(), the Facade class transforms this
into something like $app['router']->get('/', function() which is to say:
Resolve router out of the IoC Container and then call the get method. This provides a
great deal of flexibility in your code.
In our Laravel CRUD tutorial, we were making use of the DB facade and calling all kinds of
methods like DB::table() DB::insert() DB::select() DB::update() and DB::delete(). All
of these are examples of using this same Facade pattern. Our DBFacade contains this line:
<?php
Just like the Route example above, the method returns the string that identifies what object
will get resolved. So again when we call:
<?php
DB::table('blogposts')->get();
Laravel will work it’s magic and actually run something more like:
<?php
$app['db']->table('blogposts')->get();
KungFuData is now directly accessible from the container, and the DB Facade will now
use KungFuData as well. You can replace implementations in Laravel, and this new class
will be used throughout your entire application.
In Summary
• Every Facade class uses getFacadeAccessor() that returns a string to identify the
object to resolve
• The parent Facade class uses __callStatic() to trigger the resolution
• The use of Laravel’s Facade pattern provides us with pretty, elegant, static syntax.
This helps reduce some of the overhead you would normally have to deal with each
time you want to use an object. For example, creating new objects with the new
keyword, assigning initial setup to the object, placing that implementation into a
variable, and then finally accessing methods and properties doing something
like $myobject->mymethod() or $myobject->myproperty
• Maintains ability to Test Code. Integration with Mockery is built into the Facade class
to allow for quick and easy object mocking.
• Easily Switch API Versions
• Thanks to the Facade class we can use DB::insert() or Route::get() and Laravel will
do all the heavy lifting for us by instantiating our objects and calling the right methods
automagically. We don’t have to use $app[‘db’]->insert() or $app[‘router’]->get(),
Laravel will do this for you.
Wow, this is quite the Rabbit Hole we have here in Wonderland, yes Neo?
Routing is a core concept in Laravel, and it works a little differently than some
of the frameworks of the past. The Laravel Route system is very flexible, and
although a little tricky at first, once you get a good grasp of the fundamentals,
you’ll find yourself asking how you lived without it all along. Without further ado,
let’s dig into Laravel Routes!
Set Up a Custom Development Domain
Way back when, during the Install Laravel on Windows tutorial, we created an application
named blog by running a command such as: composer create-project
laravel/laravel blog --prefer-dist
What that did for us was create our project in C:wampwwwblog and in order to view our
application in a browser, we had to visit something
like http://localhost/blog/public/ Now this is probably not ideal, you just installed the
most technically advanced PHP programming framework available and you’re loading
up http://localhost/blog/public/ in the browser to view it?! Ah, no thanks. Let’s get our
own awesome dev environment set up. We’ll set this up so we can just
hit http://vegi.bit and have our app load up nice. You can choose what you like for
yours, maybe http://you.rock if you like.
• Find the line that says 127.0.0.1 localhost then right after it, add you development
domain(s)
127.0.0.1 localhost
127.0.0.1 you.rock
<VirtualHost *:80>
DocumentRoot "C:/wamp/www/blog/public"
ServerName you.rock
</VirtualHost>
<VirtualHost *:80>
DocumentRoot "C:/wamp/www"
ServerName localhost
</VirtualHost>
Include conf/extra/httpd-vhosts.conf
• Click the wamp icon in the task tray and select, Restart All Services.
Route::get('/', function()
{
return 'The first Laravel Route!';
});
We should be able to visit http://you.rock/ in your browser and be greeted with: The
first Laravel Route!
Go shorty, its yo birtday, we goin party like its yo birt…
Ahem… Ok, that’s great, we have a cool naming convention set up, so now, no matter
what you named your project when you created it, we can have a really cool URL for our
development environment.Onward!!
Routing To Closures
Most of the tutorials so far have been dealing with very simple routing to closures, which is
really the first step in learning Laravel. So when we’ve been doing this all along:
<?php
Route::get('/', function()
{
return 'The first Laravel Route!';
});
What we’ve been doing is routing to closures. This is really cool, and quite useful. In
building small applications it might be all we need in fact.
Note: Omitting either ? or null will throw an exception when visiting http://you.rock/mr
Visiting http://you.rock/mr
Produces: Misterrr Andersonnnnnn
Routes and Parameters in Action
This is really cool. Now we can use our new found powers to combine routes with eloquent
to retrieve things from our database. Recall our Many to Many Relationships in
Laravel article and let’s do something better than simply routing to /
Let’s set up a route for retrieving blogposts by tag, if no tag is given, we’ll default it to 1.
<?php
Route::get('blogposts/tag/{id?}', function($id = 1)
{
$tag = Tag::find($id);
return $tag->blogposts;
});
Route::get('blogposts/tag/{id?}', function($id = 1)
{
if (is_numeric($id))
{
$tag = Tag::find($id);
return $tag->blogposts;
}
else
{
$column = 'name'; // This is the name of the column you wish to search
Now, you can visit any of the following routes, and get the exact results you would expect!
http://you.rock/blogposts/tag
http://you.rock/blogposts/tag/1
http://you.rock/blogposts/tag/2
http://you.rock/blogposts/tag/3
http://you.rock/blogposts/tag/laravel
http://you.rock/blogposts/tag/bootstrap
http://you.rock/blogposts/tag/windows
For examples sake, here is http://you.rock/blogposts/tag/laravel
[
{
"id": 3,
"title": "Laravel Eloquent ORM Tutorial",
"body": "Eloquent is the very powerful and expressive ORM or Object Relational Mapper in
Laravel. If you know how to work with Objects in PHP, then you know how to use Eloquent! ",
"created_at": "0000-00-00 00:00:00",
"updated_at": "0000-00-00 00:00:00",
"pivot": {
"tag_id": 1,
"blogpost_id": 3
}
},
{
"id": 4,
"title": "Install Laravel on Windows",
"body": "This is going to assume we are starting from scratch using a fresh install of WAMP
2.4 on Windows.",
"created_at": "0000-00-00 00:00:00",
"updated_at": "0000-00-00 00:00:00",
"pivot": {
"tag_id": 1,
"blogpost_id": 4
}
}
Search by Slug
We can also use this method to search by slug, provided we have a slug in
our blogposts table. Note: You will need to add one now if you’d like to test this.
<?php
Route::get('blogposts/title/{id?}', function($id = 1)
{
if (is_numeric($id))
{
$blogpost = Blogpost::find($id);
return $blogpost;
}
else
{
$column = 'slug'; // This is the name of the column you wish to search
"id": 4,
"title": "Install Laravel on Windows",
"body": "This is going to assume we are starting from scratch using a fresh install of WAMP 2.4
on Windows.",
"created_at": "0000-00-00 00:00:00",
"updated_at": "0000-00-00 00:00:00",
"slug": "install-laravel-on-windows"
Route::get('blogposts/title/{id?}', function($id = 1)
{
if (is_numeric($id))
{
$blogpost = Blogpost::find($id);
return $blogpost;
}
else
{
$column = 'slug'; // This is the name of the column you wish to search
Route::get('blogposts/title/{id?}', function($id = 1)
{
if (is_numeric($id))
{
$blogpost = Blogpost::find($id);
return $blogpost;
}
else
{
$column = 'slug'; // This is the name of the column you wish to search
Parameters to Verbs
In all of our get requests so far, we have been handing it a string, and a closure. In a
generic sense it looks like this:
<?php
It is nothing more than two parameters separated by a comma. The string is the URL to
match against, and the closure is simply an anonymous function with some action to
take inside of it. Consult with Chuck Norris, I mean Douglas Crockford, for a mind bending
exercise in understanding closures in all of their glory.
The Routing Takeaway
Routing in Laravel is the glue that holds it all together. In the beginning with our small
applications, it is fine to use Explicit Routing and Routing to Closures. As we dig deeper
into Routing, we are going to want to really explore RESTful Routing and Routing with
Controllers in Laravel.
Route::get('agents', 'AgentsController@index');
So what we are saying here is that when we route to agents we’ll use
the AgentsController. This follows the format of a Collection name followed by the
word Controller. But wait, we don’t have an actual controller yet. Well that is easy to fix,
let’s use Artisan to generate one for us:
php artisan controller:make AgentsController
Bingo: Controller created successfully!
Ok, let’s navigate to our Controllers directory and see what has been created for us:
<?php
/**
* Display a listing of the resource.
*
* @return Response
*/
public function index()
{
//
}
/**
* Show the form for creating a new resource.
*
* @return Response
*/
public function create()
{
//
}
/**
* Store a newly created resource in storage.
*
* @return Response
*/
public function store()
{
//
}
/**
* Display the specified resource.
*
* @param int $id
* @return Response
*/
public function show($id)
{
//
}
/**
* Show the form for editing the specified resource.
*
* @param int $id
* @return Response
*/
public function edit($id)
{
//
}
/**
* Update the specified resource in storage.
*
* @param int $id
* @return Response
*/
public function update($id)
{
//
}
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return Response
*/
public function destroy($id)
{
//
}
Just for fun, let’s add some agents to our index method like so:
public function index()
{
return 'Agents Brown, Smith, and Jones';
}
Here, we add another route to our routes.php file. It says, when you hit the agents path,
and pass in the agent name wildcard, run the AgentsController, and call
the show method. By adding a quick snippet to our show method:
public function show($name)
{
return 'Agent '.$name.': Mister Anderson, you look surprised to see me, again.';
}
We can now visit http://you.rock/agents/smith and be greeted with the ever friendly
Agent Smith’s message.
Agent smith: Mister Anderson, you look surprised to see me, again.
What is REST?
First up, let’s talk about rest or representational state transfer. Rest was first defined by a
gentleman named Roy Fielding. Roy made use of REST to design URI or Uniform
Resource Identifiers, and HTTP 1.1. Many applications and websites now offer Web
Services, and it is becoming increasingly common to use REST for this rather than the
overly complicated SOAP.
In addition REST makes use of specific HTTP Verbs or request methods, such
as GET POST PUT and DELETE
This table gives a great overview and use cases of the various RESTful request methods:
RESTful API HTTP methods
Resource GET PUT POST
Collection URI, such List the URIs and perhaps other Replace the entire Create a new entry in the
as /resources details of the collection’s collection with another collection. The new entry’s URI
members. collection. is assigned automatically and is
usually returned by the
operation.
Element URI, such Retrieve a representation of the Replace the addressed Not generally used. Treat the
as /resources/item17 addressed member of the member of the addressed member as a
collection, expressed in an collection, or if it doesn’t collection in its own right
appropriate Internet media exist, create it. and create a new entry in it.
type.
+--------+-------------------+------+------------------------+----------------+---------------+
+--------+-------------------+------+------------------------+----------------+---------------+
+--------+-------------------+------+------------------------+----------------+---------------+
These routes are still registered to our application when we created a couple of explicitly
routed controllers in the Introduction to Laravel Controllers post. This is pretty cool that we
can run a simple command and look at all registered routes in the application, don’t you
think?!
Now open up your routes.php file, clear all routes out of it, save the file, then run the
command again:
php artisan routes
Artisan will gleefully tell us
Your application doesn’t have any routes.
Excellent! Now we know how to check on the status of our registered routes at any time.
Route Resource
Warning: Mind blowing activities beyond this point.
Let’s create a route resource in our routes.php file. It’s really easy, we just add a snippet
like this:
1 Route::resource('blogposts', 'BlogpostsController');
What this tells us is that we are creating a blogposts resource and our BlogpostsController
will handle actions taken on this resource. That one line of code just did a lot for us. Ok so
what’s the big deal Jack? Well, why don’t we run the command again and see what
happens:
php artisan routes
+--------+--------------------------------+-------------------+-----------------------------+----------------+---------------+
+--------+--------------------------------+-------------------+-----------------------------+----------------+---------------+
+--------+--------------------------------+-------------------+-----------------------------+----------------+---------------+
Whoa. What just happened? Well, Laravel just registered 8 RESTful routes for you in the
blink of an eye.
Ok so now we need to start thinking about resources. In this case above, blogposts is our
resource. So what does this mean? Let’s go through line by line:
GET blogposts
Sending a GET request to the http://you.rock/blogposts URI will list all blog posts.
Controller Method: index()
GET blogposts/create
Sending a GET request to the http://you.rock/blogposts/create URI should give us a
form to create a new blog post.
Controller Method: create()
POST blogposts
Once you enter all of the information into your form, it should send a POST request
to http://you.rock/blogposts which will store it in the database.
Controller Method: store()
GET blogposts/{blogposts}
Sending a GET request
to http://you.rock/blogposts/blogpostid or http://you.rock/blogposts/slug-of-
blogpost should enable viewing of a specific blogpost.
Controller Method: show()
GET blogposts/{blogposts}/edit
Sending a GET request
to http://you.rock/blogposts/blogpostid/edit or http://you.rock/blogposts/slug-of-
blogpost/edit should provide a populated form to edit an existing blogpost.
Controller Method: edit()
PUT blogposts/{blogposts}
Sending a PUT request
to http://you.rock/blogposts/blogpostid or http://you.rock/blogposts/slug-of-
blogpost should update a specific blogpost.
Controller Method: update()
PATCH blogposts/{blogposts}
PATCH is similar to PUT.
DELETE blogposts/{blogposts}
Sending a DELETE request
to http://you.rock/blogposts/blogpostid or http://you.rock/blogposts/slug-of-
blogpost should destroy or delete a specific blogpost.
Controller Method: destroy()
Awesome! Since we have a model already made, let’s add some code to the index() method
of our Blogposts Controller so we can test our new resourceful routing.
<?php
/**
* Display a listing of the resource.
*
* @return Response
*/
public function index()
{
return Blogpost::all();
}
{
"id": 1,
"title": "You Should Use Twitter Bootstrap!",
"body": "If you are a design savvy person, you may have noticed that Vegibit uses the Twitter
Bootstrap Framework. I freaking love this framework, and you should too, or rather if you’re
unfamiliar, you will love it by the time you finish reading this article.",
"created_at": "0000-00-00 00:00:00",
"updated_at": "0000-00-00 00:00:00",
"slug": "you-should-use-twitter-bootstrap"
},
{
"id": 2,
"title": "Twitter Bootstrap Modal Tutorial",
"body": "Modals are a fun way to add interactivity to your website. When a user needs to make
a choice, or confirm an action, the classic jquery modal popup makes perfect sense.",
"created_at": "0000-00-00 00:00:00",
"updated_at": "0000-00-00 00:00:00",
"slug": "twitter-bootstrap-modal-tutorial"
},
{
"id": 3,
"title": "Laravel Eloquent ORM Tutorial",
"body": "Eloquent is the very powerful and expressive ORM or Object Relational Mapper in
Laravel. If you know how to work with Objects in PHP, then you know how to use Eloquent! ",
"created_at": "0000-00-00 00:00:00",
"updated_at": "0000-00-00 00:00:00",
"slug": "laravel-eloquent-orm-tutorial"
},
{
"id": 4,
"title": "Install Laravel on Windows",
"body": "This is going to assume we are starting from scratch using a fresh install of WAMP
2.4 on Windows.",
"created_at": "0000-00-00 00:00:00",
"updated_at": "0000-00-00 00:00:00",
"slug": "install-laravel-on-windows"
},
{
"id": 5,
"title": "Install and Configure Windows Server 2012 with Windows Powershell",
"body": "Windows PowerShell is an amazingly powerful tool to help you with common windows
administrative tasks. If you are comfortable with one of the myriad of scripting languages available
today, Powershell will be easy for you to learn while also providing the benefits of command line
administration. ",
"created_at": "0000-00-00 00:00:00",
"updated_at": "0000-00-00 00:00:00",
"slug": "install-and-configure-windows-server-2012-with-windows-powershell"
}
Oh Yeah Baby! Hey now, Hey now, here what I say now! So how does it work? Well here
is how the code would flow:
<?php
/**
* Display a listing of the resource.
*
* @return Response
*/
public function index()
{
return Blogpost::all();
}
Let’s start using Views instead! When we want to load a view, we’ll do so by using
the make() method from the View Facade. We’ll also want to pass whatever data we need
on over to the view and we can do it in one of three ways.
// using the with method
return View::make('blogposts/index')->with('blogposts', $blogposts);
Master Pages
We’re going to start by creating a master page. The master page holds any repetitive html
that we don’t want to have to recreate in all of the individual views. We’ll include jQuery
and Twitter Bootstrap in this master page so we can have access to all of their great
benefits. This file will reside in the /app/views/layouts directory.
<!doctype html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css">
<script src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
<meta charset="utf-8">
<title>Larablog</title>
</head>
<body>
<div class="container">
<div>
<h1>{{ link_to('/', 'Larablog') }}</h1>
<p class="lead">Laravel, Blade, and Bootstrap working in harmony.</p>
</div>
<div class="row">
<div class="col-sm-8 blog-main"> @yield('content') </div>
</div>
</div>
</body>
</html>
Cool! In the snippet above you’ll notice two things that may look a little peculiar.
{{ link_to('/', 'Larablog') }}
The {{ and }} indicate sections that will get echoed out to the screen. This line also makes
use of the link_to function so that we can create a home link so to speak on our blog
page that links to the root. The link_to function takes two arguments, the path you’ll link
to, and the anchor text.
@yield('content')
The @yield keyword is a way to do code substitution or short codes so to speak. We’ll
define what we are actually going to put in this yielded area in our view files.
@section('content')
@foreach ($blogposts as $blogpost)
<li> {{ link_to("/blogposts/{$blogpost->slug}", $blogpost->title) }} </li>
@endforeach
@stop
show.blade.php
@extends('layouts.default')
@section('title')
{{ $blogpost->title }}
@stop
@section('content')
<h3> {{ $blogpost->title }} </h3>
<p> {{ $blogpost->body }} </p>
@stop
This might be a little new to you, it was to me. In fact I would say there are a lot of pros and
cons to using a templating engine, but since we’re really trying to be Laravel Purists here,
we’ll put in the extra effort and dig in to Blade. The view files need to begin with
the @extends keyword like you see here in order to reference the master page to use. In
addition, you define areas of code to inject into the master page by defining sections using
the @section and @stop keywords. All of the normal programming constructs, and some
new ones, are available to you as you see here.
If Statements
@if (count($blogposts) === 1)
I have one blogpost!
@elseif (count($blogposts) > 1)
I have several blogposts!
@else
I don't have any blogposts!
@endif
@unless (Auth::check())
You are not signed in.
@endunless
Loops
@for ($i = 0; $i < 10; $i++)
The current value is {{ $i }}
@endfor
@while (true)
<p>I'll keep looping!</p>
@endwhile
Includes
@include('view.name')
/**
* Display a listing of the resource.
*
* @return Response
*/
public function index()
{
$blogposts = Blogpost::all();
return View::make('blogposts/index')->withBlogposts($blogposts);
}
/**
* Show the form for creating a new resource.
*
* @return Response
*/
public function create()
{
//
}
/**
* Store a newly created resource in storage.
*
* @return Response
*/
public function store()
{
//
}
/**
* Display the specified resource.
*
* @param int $id
* @return Response
*/
public function show($id)
{
if (is_numeric($id))
{
$blogpost = Blogpost::find($id);
return View::make('blogposts/show')->withBlogpost($blogpost);
}
else
{
$column = 'slug'; // This is the name of the column you wish to search
/**
* Show the form for editing the specified resource.
*
* @param int $id
* @return Response
*/
public function edit($id)
{
//
}
/**
* Update the specified resource in storage.
*
* @param int $id
* @return Response
*/
public function update($id)
{
//
}
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return Response
*/
public function destroy($id)
{
//
}
By making use of the model, we can fetch whatever data we want from the database.
Once the controller has used the model to fetch the data from the database, it will go
ahead and render a view using View::make() passing along any required data. When the
controller instructs to make the view, Laravel will intelligently make use of the master page
in addition to the snippets of html found in the view files to create the final rendered page.
Great! Viewing individual posts using a pretty URL syntax works too!
Another bonus is that by including Twitter Bootstrap in the master page, we can see the
visual looks a whole lot better than when we were first just dumping JSON to the browser.
When we just want to test out our logic and not worry about the front end, it is still great to
be able to simply return JSON or use the dd(), or die dump function.
This is really exciting, we’re making a ton of progress in getting our skills up to speed using
Laravel!
Laravel Form Class
Getting the beginnings of our RESTful application up and running was a big
accomplishment for us! At this point, we’d like to jump into Laravel Forms and
learn how Laravel handles form operations so that we can easily create or
delete a blog post from our web interface, rather than populating our database
via the mysql console, phpMyAdmin, or some other means. Let’s get our form
on!
This instructs our application to fetch the create view from the blogposts folder and render
a view. If we want this to work, we’re going to need to create a view! Navigating to
our app/views/blogposts folder, we can now create the view that will display the form.
Following convention, this file will be named create.blade.php and will look something like
this:
@extends('layouts.default')
@section('content')
<h4> Create a New Blog Post </h4>
{{ Form::open( [ 'route' => 'blogposts.store' ] ) }}
<div> {{ Form::label('title', 'Title: ') }}
{{ Form::text('title', '', array('class' => 'form-control')) }}
</div>
<div>
{{ Form::label('body', 'Body: ') }}
{{ Form::textarea('body', '', array('class' => 'form-control')) }}
</div>
<div>
{{ Form::submit('Create Post', array('class' => 'btn btn-info')) }}
</div>
{{ Form::close() }}
@stop
Alright!Let’s take a look at what we’ve got here. First, we can see this
view @extends from layouts.default just like our other view files. In
the @section(‘content’) we find our first inkling of a form. We use
the Form::open method to open the form. By default, the Form::open method will POST to
the current URI, but in keeping with our RESTful development style so far, we are going to
want to POST to the blogposts collection. By passing in the array of [ 'route' =>
'blogposts.store' ] we can ensure the action is correct. The resulting HTML on our page
will look something like this as a result of this coding convention:
<form method="POST" action="http://you.rock/blogposts" accept-charset="UTF-8"><input name="_token"
type="hidden" value="ucAk7v1Y9BEhUXF68bONk3bOwW2gnTo7mPVOqdsZ">
We can see the method is POST, the action is http://you.rock/blogposts, and an added
freebie is the automatic creation of a hidden input token to aid in security. As a refresher, it
may help to run php artisan routes to remind us of the relationship between URI, Name,
and Action. Here we are referencing the named route blogpost.store which
should POST to /blogposts (it does) and use the store()method of the BlogpostsController
(it will)!
+--------+--------------------------------+-------------------+-----------------------------+----------------+---------------+
+--------+--------------------------------+-------------------+-----------------------------+----------------+---------------+
+--------+--------------------------------+-------------------+-----------------------------+----------------+---------------+
Let’s see what the remaining Laravel helper methods are buying us in terms of HTML
output to the browser:
<form method="POST" action="http://you.rock/blogposts" accept-charset="UTF-8"><input name="_token"
type="hidden" value="JUhDwq5ey407X1FyiONL9qWZvJx0pRq61SJa5DMV"><div> <label for="title">Title:
</label> <input class="form-control" name="title" type="text" value="" id="title">
</div>
<div>
<label for="body">Body: </label> <textarea class="form-control" name="body" cols="50" rows="10"
id="body"></textarea>
</div>
<div>
<input class="btn btn-info" type="submit" value="Create Post">
</div>
</form>
"_token": "JUhDwq5ey407X1FyiONL9qWZvJx0pRq61SJa5DMV",
"title": "Twitter Bootstrap is Fun to Use",
"body": "Try out the new and improved Twitter Bootstrap. It freshens breath and makes your
website awesome"
Well Jumping Jackhammers, would you take a look at that? We can see that it is easy to
test our forms first before anything actually hits the database. Now we can update
the store() method further. Check it out:
public function store()
{
$blogpost = new Blogpost;
$blogpost->title = Input::get('title');
$blogpost->body = Input::get('body');
return Redirect::route('blogposts.index');
}
Looks reasonable to me, should we hit the Create Post button? I think we should, here we
go:
Well check it out friends. What is that I see as the last entry on our index page? Yes, it is in
fact The History of Twitter Bootstrap. Our store() method worked as intended!
@section('title')
{{ $blogpost->title }}
@stop
@section('content')
<h3> {{ $blogpost->title }} </h3>
<p> {{ $blogpost->body }} </p>
Let’s test it out now, go ahead and hit that delete button!
Success!We can see upon clicking the delete button, we are directed back to the index
page, and if you notice in the list of posts, The History of Twitter Bootstrap is no longer
there! Soon, we can add Laravel Validation to our small app as well!
Laravel Validation
In our last episode when we worked with the Laravel Form Class, we were able
to add some great functionality to our small RESTful blog application. We saw
how the Laravel Form Class made it easy to bring forth forms with great power
and efficiency. We also used the great Twitter Bootstrap Framework to spice up
the looks just a little bit. There is something we need to add though to the forms
we have created and that would be Validation. Validation is super important for
any web based application. It is certainly not good to let users submit blank
information, or worse, malicious information into our web forms. By using
validation, we can overcome this nuisance. Let’s jump into Laravel Validation!
Before the current glory days of working with Laravel, web builders would need to string
together complex collections of regular expressions in the form of either client side
javascript, server side PHP, or a combination of both. Frankly, I’ve always found the task
of having to create all this validation repetitive and a bit dull. So instead of doing things the
old way and getting our brains wracked up over dealing with the ever cryptic regular
expressions, we can simply implement the Laravel Validation Class and get rocking and
rolling with solid validation in no time.
What we do here is pass in an array, and each key of the array maps to a field in the
database. The corresponding value for each key refers to some type of validation. There
are many rules you can use here. In our case we are just going to use required but if we
wanted to we could use any of the following available rules to validate the type and value
of the data to be inserted into the given field in the database: Required With, Image (File),
Required Without, After (Date), Integer, Size, Regular Expression, Date, Digits, Alpha,
Active URL, Required If, MIME Types, Different, URL, IP Address, Date Format, E-Mail,
Between, Required With All, Numeric, Before (Date), Unique (Database), Required, In,
Same, Alpha Numeric, Alpha Dash, Digits Between, Exists (Database), Max, Required
Without All, Confirmed, Min, Not In, and Accepted.
When we create an instance of the Validation class by using Validator::make, we now
have access to two methods which are oh so appropriately named fails() and passes().
We can use these methods to carry out the validation. So let’s do something super easy at
first.
We’ll add this to our BlogpostsController before we create a new instance of a Blogpost.
<?php
@section('content')
<h4> Create a New Blog Post </h4>
{{ Form::open( [ 'route' => 'blogposts.store' ] ) }}
<div> {{ Form::label('title', 'Title: ') }}
{{ Form::text('title', '', array('class' => 'form-control')) }}
{{ $errors->first('title', '<div class="alert alert-danger"><b>:message</b></div>') }}
</div>
<div>
{{ Form::label('body', 'Body: ') }}
{{ Form::textarea('body', '', array('class' => 'form-control')) }}
{{ $errors->first('body', '<div class="alert alert-danger"><b>:message</b></div>') }}
</div>
<div>
{{ Form::submit('Create Post', array('class' => 'btn btn-info')) }}
</div>
{{ Form::close() }}
@stop
Model
class Blogpost extends Eloquent {
protected $guarded = array();
Now we have moved the validation rules over to the Model and everything still works the
same as before.
Create a static method in the model to validate
We could also clean up the controller by moving the logic into a static method defined in
the model, then just call that method from the controller, let’s see that now:
Model
class Blogpost extends Eloquent {
protected $guarded = array();
if($validation->passes()) {
return true;
}
static::$messages = $validation->messages();
return false;
}
}
Controller
public function store()
{
if( ! Blogpost::passesValidation(Input::all()) ) {
return Redirect::back()->withInput()->withErrors(Blogpost::$messages);
}
return Redirect::route('blogposts.index');
}
Now this is pretty slick. We have moved most of the logic over to the model, and just use a
couple simple lines of code in the store() method of the controller to complete the
validation, and everything works like a champ. One small drawback is that we did make
use of static methods and properties in order to do so. This goes against the overlords of
the PHP society, so we will need to fix that.
We can instead inject an instance of the Blogpost Model into the controller via it’s
constructor. Let’s begin by adding this code to the controller:
class BlogpostsController extends BaseController {
Now that we have injected an instance of the Blogpost Model right into
the BlogpostsController, we will need to remove all of the static references to that class
and replace with the more traditional syntax. In fact, you could do a find on
any Blogpost:: and replace with $this->blogpost-> , that will get our controller updated.
Don’t forget to remove the $ symbol in front of your variables when making this change.
When you reference a variable in a static fashion, it is included. An example
is static::$messages vs $this->messages. Note that in the static example the $ is
present, but in the dependency injection style only the $this keyword has the $.
If we test out the updated code, we’ll find all functionality to be the same. The benefit is
that by using dependency injection and letting Laravel handle the creation of an object
instance using the IoC container, we get code that is more dependable, testable, and
flexible when a change in implementation is needed. The fully updated code looks like this:
BlogpostsController (controller)
<?php
/**
* Show the form for creating a new resource.
*
* @return Response
*/
public function create()
{
return View::make('blogposts.create');
}
/**
* Store a newly created resource in storage.
*
* @return Response
*/
public function store()
{
if( ! $this->blogpost->passesValidation(Input::all()) ) {
return Redirect::back()->withInput()->withErrors($this->blogpost->messages);
}
return Redirect::route('blogposts.index');
}
/**
* Display the specified resource.
*
* @param int $id
* @return Response
*/
public function show($id)
{
if (is_numeric($id))
{
$blogpost = $this->blogpost->find($id);
return View::make('blogposts/show')->withBlogpost($blogpost);
}
else
{
$column = 'slug'; // This is the name of the column you wish to search
/**
* Show the form for editing the specified resource.
*
* @param int $id
* @return Response
*/
public function edit($id)
{
//
}
/**
* Update the specified resource in storage.
*
* @param int $id
* @return Response
*/
public function update($id)
{
//
}
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return Response
*/
public function destroy($id)
{
$column = 'slug'; // This is the name of the column you wish to search
Blogpost (model)
<?php
public $messages;
if($validation->passes()) {
return true;
}
$this->messages = $validation->messages();
return false;
}
}
Of course this code could be made cleaner than this, but the goal here was to start by
getting basic validation working. Once we got the basic validation working, we moved to
more of a best practice style of dependency injection. Hopefully we accomplished those
goals, and I think we did!
// Finds a string between a given start and end point. You can include
// or exclude the start and end point
public static function find_between($string, $start, $end, $incorexc) {
$temp = self::split_string ( $string, $start, 'after', $incorexc );
return self::split_string ( $temp, $end, 'before', $incorexc );
}
return $string;
}
}
Note!We did make a few small changes to this class as compared to its function based file
from the prior lesson. The constants have been removed, and any calls to functions within
the same class are now prefixed with the self:: operator. This is to tell PHP that we want
to use a function that is a part of this class. Otherwise, if we try to use the functions in our
code without first using self:: we will get an error.
2. Create a libraries folder
In the app folder of your Laravel project, we can create a libraries folder so we have a
place to hold our library code. Take the code from step 1 and save it to a file
named Stringhelpers.php in this folder. In our folder that would
be C:wampwwwblogapplibraries since in our earlier adventures we had already created a
blog application.
app_path().'/commands',
app_path().'/controllers',
app_path().'/models',
app_path().'/database/seeds',
app_path().'/libraries',
));
4. Edit composer.json
We’ll need to edit composer.json to add "app/libraries" to the autoload array. You can
learn all about autoloading with composer in our examination of Composer. In the root
directory C:wampwwwblog of your Laravel application you will find the composer.json file.
Open this file up and add "app/libraries"to the autoload array. It might look something
like this upon completion:
"classmap": [
"app/commands",
"app/controllers",
"app/models",
"app/database/migrations",
"app/database/seeds",
"app/tests/TestCase.php",
"app/libraries"
],
5. Run composer dump
If you are using windows and have composer installed, the easiest way to do this is to right
click on your Laravel project folder and select ‘Use Composer Here‘. This will open up a
command prompt in your Laravel project directory and you can now just type ‘composer
dump‘. You’ll see it generate some autoload files for you just like this:
Route::get('/stringhelpers', function() {
$string = 'We like to program in PHP and we like to use the Laravel Framework!';
var_dump($string);
});
This says that when we visit http://you.rock/stringhelpers, we’ll initialize a basic string
which will contain the text We like to program in PHP and we like to use the Laravel
Framework! Then we’ll call our helper functions via static methods and var_dump the result
to the screen. Let’s do it!
http://you.rock/stringhelpers
string 'We like to program in PHP and we like to use the Laravel Framework!' (length=67)
string 'like to program in PHP and we like to use the Laravel Framework!' (length=64)
array (size=2)
0 => string 'We like to' (length=10)
1 => string 'we like to' (length=10)
string ' program in PHP and use the Laravel Framework!' (length=47)
The functions are working! That is really cool, but let’s clean things up just a
Well look at that!
little bit by creating a view with a form so that we have a place where we can easily submit
text and operate on that text using our new functions.
@section('content')
<h4>String Helper Library</h4>
{{ Form::open( ) }}
<div>
{{ Form::label('string', 'String: ') }}
{{ Form::textarea('string', '', array('class' => 'form-control')) }}
</div>
<div>
{{ Form::label('start', 'Start: ') }}
{{ Form::text('start', '', array('class' => 'form-control')) }}
</div>
<div>
{{ Form::label('end', 'End: ') }}
{{ Form::text('end', '', array('class' => 'form-control')) }}
</div>
<div>
{{ Form::label('incorexc', 'Include or Exclude Markers (only for the find_between() method):') }}
{{ Form::text('incorexc', '', array('class' => 'form-control')) }}
</div>
<div>
{{ Form::label('function', 'Run this function') }}
{{ Form::select('function', array('fb' => 'find_between()', 'fa' => 'find_all()', 'd' =>
'delete()')) }}
</div>
<div>
{{ Form::submit('Get Data', array('class' => 'btn btn-info')) }}
</div>
{{ Form::close() }}
<div>
@stop
Route::get('/stringhelpers', function() {
return View::make('stringhelpers/stringhelpers');
});
switch ($function) {
case 'fb':
$data['result'] = Stringhelpers::find_between($string, $start, $end, $incorex);
$data['function'] = 'find_between()';
$data['description'] = 'This function finds a string between a given start and end point.';
$data['string'] = $string;
$data['start'] = $start;
$data['end'] = $end;
case 'd':
$data['result'] = Stringhelpers::delete($string, $start, $end);
$data['function'] = 'delete()';
$data['description'] = 'This function uses str_replace to remove any unwanted substrings within
in a string.';
$data['string'] = $string;
$data['start'] = $start;
$data['end'] = $end;
default:
}
});
There is a fair amount of logic happening here, yet it is pretty straightforward. Let’s walk
through it:
• We know when a form is submitted in Laravel, it uses the post method. As such, we
use Route::post for this route.
• Next we use the Input Façade to capture all of the form input and place that data in
variables we can use.
• Now we have to determine which helper function will run. We’ll do this in
a switch statement.
• Finally, we’ll use the View Façade to make a view, and pass the resulting $data to it,
based on which branch of the switch statement runs.
We’re almost ready to rock and roll, but we need a view for the result. Go ahead
Excellent!
and put the following snippet into a file called result.blade.php:
@extends('layouts.default')
@section('content')
You just ran the <code>{{ $function }}</code> function on the string:<br><br> <b>{{ $string }}</b>.
<br><br> {{ $description }}<br><br>
The start point was <code>{{ $start }}</code> while the end point was <code>{{ $end }}</code>, and
the result of this operation @if (is_array($result)) are the sub strings:<br><br> @else is the
substring:<br><br> @endif
@if (is_array($result))
@foreach ($result as $r)
<b class="text-primary">{{ $r }}</b> <br>
@endforeach
@else
<b class="text-primary">{{ $result }}</b>
@endif
@stop
Ok Friends, its Go Time! Let’s test out the functions via our form one at a time.
find_between()
Here you can see we input a fairly lengthy string, we then use the word string as a start
point, functions as an end point, and include these in the return value.
For this example we use the word string as a start point, functions as an end point,
and exclude these in the return value.
find_all()
For the remaining tests, we’ll use the same start and end point of string and functions,
while leaving the last field blank since we do not need that parameter for these function
calls.
delete()
Conclusion
Laravel has an incredible amount of useful tools and built in helper functions as well. We
hope to dive into the native helpers of Laravel soon. When we visit the official laravel
documentation, we see a plethora of helper functions for Arrays, Paths, Strings, URLs, as
well as several Miscellaneous helpers. There are times however when we might want to
create our own helpers, or import existing libraries we are familiar with. In this lesson we
took action to create our own laravel custom helper functions. It’s a fairly straightforward
process where we create the class file we want, place it into a libraries folder within the
app folder, configure the global.php file, add the libraries folder to the compser.json file,
and then run composer dump. Running composer dump generates the autoload files
automatically and once we complete these steps, we can start using these custom helper
functions in Laravel right away. The helper functions here are fairly basic, but the outline or
process to follow will work for any size or type of helper class that you may want to load
into laravel. This makes for a very flexible development architecture that is super fun to
use!
Most websites will need a way to allow users to log in so that they can access
resources, update information, and so on. Some frameworks like Codeigniter
do not have a built in authentication system. In a scenario like that, you would
have to write your own, or implement a third party solution. With Laravel, user
authentication is baked right in. Let’s take a look at how we can put Laravel
Auth to use!
Once all this is complete run composer update, then run php artisan generate:migration
create_users_table --fields="username:string, email:string:unique,
password:string"
Before we forget, lets make sure our database connections are configured
in app/config/database.php. Since we are rebels in the local environment, we’re just going
to use root with no password
'mysql' => array(
'driver' => 'mysql',
'host' => 'localhost',
'database' => 'authdemo',
'username' => 'root',
'password' => '',
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
)
While we’re at it, let’s have a look at the migration which was created for us by using the
generate command.
<?php
use IlluminateDatabaseMigrationsMigration;
use IlluminateDatabaseSchemaBlueprint;
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('users', function(Blueprint $table)
{
$table->increments('id');
$table->string('username');
$table->string('email')->unique();
$table->string('password');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('users');
}
Onward! Ok, now that we have a user in the Users table, we’re going to need a form to allow
someone to log in. We can use a route resource to accomplish this goal. Let’s set up the
routes file like so:
<?php
/*
|--------------------------------------------------------------------------
| Application Routes
|--------------------------------------------------------------------------
|
| Here is where you can register all of the routes for an application.
| It's a breeze. Simply tell Laravel the URIs it should respond to
| and give it the Closure to execute when that URI is requested.
|
*/
Route::get('login', 'SessionsController@create');
Route::get('logout', 'SessionsController@destroy');
Route::resource('sessions', 'SessionsController');
We can view our routes using php artisan routes
+--------+-----------------------------------+------------------+----------------------------+----------------+---------------+
+--------+-----------------------------------+------------------+----------------------------+----------------+---------------+
+--------+-----------------------------------+------------------+----------------------------+----------------+---------------+
We can now generate a controller that will handle all the routes we just set up using php
artisan generate:controller SessionsController
In this episode we are using the RESTful development style. If the routes
Friendly Alert!
above look like a foreign language, check out our episode on RESTful Controllers and
you’ll be good to go.
Here is our new controller in all of its glory:
<?php
/**
* Display a listing of the resource.
* GET /sessions
*
* @return Response
*/
public function index()
{
//
}
/**
* Show the form for creating a new resource.
* GET /sessions/create
*
* @return Response
*/
public function create()
{
return View::make('sessions.create');
}
/**
* Store a newly created resource in storage.
* POST /sessions
*
* @return Response
*/
public function store()
{
//
}
/**
* Display the specified resource.
* GET /sessions/{id}
*
* @param int $id
* @return Response
*/
public function show($id)
{
//
}
/**
* Show the form for editing the specified resource.
* GET /sessions/{id}/edit
*
* @param int $id
* @return Response
*/
public function edit($id)
{
//
}
/**
* Update the specified resource in storage.
* PUT /sessions/{id}
*
* @param int $id
* @return Response
*/
public function update($id)
{
//
}
/**
* Remove the specified resource from storage.
* DELETE /sessions/{id}
*
* @param int $id
* @return Response
*/
public function destroy($id)
{
//
}
Now we need to create the actual form to handle this. We’ll create a master page and
embed bootstrap so things look better than bare html. Here is a starting point for the
master page and the form. With the laravel form class, you can specify classes to add via
an array. For any html elements that laravel is generating for the form, we will add the
class using the array. Any other elements we’ll just add the class in the view file.
default.blade.php
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Laravel Auth Tutorial</title>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<body>
<div class="container">
<div>
<h1>Laravel Auth Tutorial</h1>
</div>
@yield('content')
</div>
</body>
</html>
create.blade.php
@extends('layouts.default')
@section('content')
{{ Form::open(array('route' => 'sessions.store', 'class'=>'form-horizontal' )) }}
<div class="form-group">
<div class="col-lg-1">
{{ Form::label('email', 'Email:') }}
</div>
<div class="col-lg-7">
{{ Form::text('email', '', array('class' => 'form-control')) }}
</div>
</div>
<div class="form-group">
<div class="col-lg-1">
{{ Form::label('password', 'Password:') }}
</div>
<div class="col-lg-7">
{{ Form::password('password', array('class' => 'form-control')) }}
</div>
</div>
<div class="form-group">
<div class="col-lg-8">
{{ Form::submit('Login', array('class' => 'btn btn-lg btn-info btn-block')) }}
</div>
</div>
{{ Form::close() }}
@stop
Shweet!
Update SessionsController
So we have a form going, and things look to be routing properly. We’ll now need to update
the SessionsController so that the store method will handle a login once a user fills out
the form and clicks login. We’ll set up some logic so that both the login and logout routes
will handle their requests when visited. Another thing to note, we are going to need to
update our migrations to include $table->text('remember_token')->nullable();,
otherwise the Redirect::to(); after the Auth::logout(); will fail as I found out
This seemed to work, your mileage may vary:
run php artisan migrate:make users_add_remembertoken
Add this code to your new migration file:
<?php
use IlluminateDatabaseSchemaBlueprint;
use IlluminateDatabaseMigrationsMigration;
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table("users", function($table) {
$table->text('remember_token')->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
//
}
/**
* The database table used by the model.
*
* @var string
*/
protected $table = 'users';
/**
* The attributes excluded from the model's JSON form.
*
* @var array
*/
protected $hidden = array('password', 'remember_token');
We can now update the store and destroy methods like so:
store()
public function store()
{
$input = Input::all();
if($attempt) {
return Redirect::to('user');
} else {
return Redirect::to('login');
}
}
destroy()
public function destroy()
{
Auth::logout();
Session::flush();
return Redirect::to('login');
We won’t do anything too fancy, if the user is logged out, we’re just going to send her back
to the login form. You could do all kinds of nice things with custom views for different
scenarios and so on, but we just want to see the authentication login and logout
functionality of laravel at work here. We’ll set up a user view and update the routes file
now.
user.blade.php
@extends('layouts.default')
@section('content')
<div class="col-lg-8">
<h4 class="alert alert-success">Hi there friend! Thanks for registering your email of {{
Auth::user()->email }} </h4>
</div>
@stop
updated routes.php
<?php
/*
|--------------------------------------------------------------------------
| Application Routes
|--------------------------------------------------------------------------
|
| Here is where you can register all of the routes for an application.
| It's a breeze. Simply tell Laravel the URIs it should respond to
| and give it the Closure to execute when that URI is requested.
|
*/
Route::get('user', function() {
return View::make('sessions/user');
})->before('auth');
Route::get('login', 'SessionsController@create');
Route::get('logout', 'SessionsController@destroy');
Route::resource('sessions', 'SessionsController');
Ok, pretty standard stuff. You’ll note that we do make use of ->before(‘auth’); and all this
does is tell laravel, if a user tries to hit the user route, send them packing if they’re not
logged in. We’re ready for action.
First we’ll visit http://localhost/authdemo/public/login and fill in our information to
login.
The Repository Pattern can be very helpful to you in order to keep your code a
little cleaner and more readable. In fact, you don’t have to be using Laravel in
order to use this particular design pattern. For this episode however, we will use
the object oriented php framework Laravel to show how using repositories will
make our controllers a bit less verbose, more loosely coupled, and easier to
read. Let’s jump in!
This would be pretty typical code for using Eloquent to interact with the database which
holds listings of houses for sale. It will work just fine, but the controller is now tightly
coupled to Eloquent. We can inject a repository instead to create a loosely coupled version
of the same code. This loose coupling makes it easy to swap implementations at a later
time.
use House;
use IlluminateSupportServiceProvider;
This code basically says, when you see the controller type
hinting HouseRepositoryInterface, we know you want to make use of
the DbHouseRepository.
'IlluminateFoundationProvidersArtisanServiceProvider',
'IlluminateAuthAuthServiceProvider',
'IlluminateCacheCacheServiceProvider',
'IlluminateSessionCommandsServiceProvider',
'IlluminateFoundationProvidersConsoleSupportServiceProvider',
'IlluminateRoutingControllerServiceProvider',
'IlluminateCookieCookieServiceProvider',
'IlluminateDatabaseDatabaseServiceProvider',
'IlluminateEncryptionEncryptionServiceProvider',
'IlluminateFilesystemFilesystemServiceProvider',
'IlluminateHashingHashServiceProvider',
'IlluminateHtmlHtmlServiceProvider',
'IlluminateLogLogServiceProvider',
'IlluminateMailMailServiceProvider',
'IlluminateDatabaseMigrationServiceProvider',
'IlluminatePaginationPaginationServiceProvider',
'IlluminateQueueQueueServiceProvider',
'IlluminateRedisRedisServiceProvider',
'IlluminateRemoteRemoteServiceProvider',
'IlluminateAuthRemindersReminderServiceProvider',
'IlluminateDatabaseSeedServiceProvider',
'IlluminateSessionSessionServiceProvider',
'IlluminateTranslationTranslationServiceProvider',
'IlluminateValidationValidationServiceProvider',
'IlluminateViewViewServiceProvider',
'IlluminateWorkbenchWorkbenchServiceProvider',
'repotutrepositoriesBackendServiceProvider'
),
use repotutrepositoriesHouseRepositoryInterface;
}
}
/*
|--------------------------------------------------------------------------
| Application Routes
|--------------------------------------------------------------------------
|
| Here is where you can register all of the routes for an application.
| It's a breeze. Simply tell Laravel the URIs it should respond to
| and give it the Closure to execute when that URI is requested.
|
*/
Route::resource('houses', 'HousesController');
• 8: Update composer.json
If you have not done so already, make sure that the namespace we are referencing
is in your composer.json. Note the addition of "psr-4":{"repotut\": "app/repotut"
} which tells composer to autoload the classes within the repotut namespace.
{
"name": "laravel/laravel",
"description": "The Laravel Framework.",
"keywords": ["framework", "laravel"],
"license": "MIT",
"require": {
"laravel/framework": "4.2.*"
},
"autoload": {
"classmap": [
"app/commands",
"app/controllers",
"app/models",
"app/database/migrations",
"app/database/seeds",
"app/tests/TestCase.php"
],
"psr-4":{
"repotut\": "app/repotut"
}
},
"scripts": {
"post-install-cmd": [
"php artisan clear-compiled",
"php artisan optimize"
],
"post-update-cmd": [
"php artisan clear-compiled",
"php artisan optimize"
],
"post-create-project-cmd": [
"php artisan key:generate"
]
},
"config": {
"preferred-install": "dist"
},
"minimum-stability": "stable"
}
$houses = array($house1,$house2,$house3);
return $houses;
}
use IlluminateSupportServiceProvider;
Repositories Conclusion
As you can see, it seems like a lot of steps to get Repositories working in your application.
There are a few steps involved, no doubt about it. If you are going to be responsible for
maintaining a piece of code for the long term however, you are going to reap the benefits
of taking the time to correctly architect your app in the beginning. Consider it a form of
delayed gratification, which in this day and age seems like a forgotten art.
When using Laravel, there is a great way to listen for events and then take
actions based on those events by using the Event Facade. This is also known
as an Observable Implementation. By using the Event Facade, we can listen for
or subscribe to events that may occur, and then immediately take action. It’s a
great way to keep your code clean, as well as having a dedicated class to
handle events.
Event::listen('user.login', function()
{
var_dump('a user just logged in');
});
Route::get('/', function()
{
Event::fire('user.login');
});
When we visit the homepage, we’ll see the event fired successfully string 'a user just
logged in' (length=21).
Event::listen('user.login', function($user)
{
var_dump($user->toArray());
});
Route::get('/', function()
{
$user = User::first();
Event::fire('user.login', $user);
});
/*
array (size=4)
'id' => int 1
'email' => string 'vegibit@eventtut.com' (length=20)
'created_at' => string '2014-07-29 10:47:33' (length=19)
'updated_at' => string '2014-07-29 10:47:33' (length=19)
*/
You can use the Event::fire() and Event::listen() methods anywhere you like. Often
times, you can use them right in your controllers.
Event::subscribe('UserEventHandler');
class UserEventHandler {
Route::get('/', function()
{
// here is where the event fires
Event::fire('user.logout');
});
The above code places our event handling in a dedicated class. In this case we name
it UserEventHandler. Then, we can use Event::subscribe(‘UserEventHandler’) to listen
for events to get fired. In our home route, we then fire the user.logout event, and its
associated listener triggers it’s logic which in this case is to simply echo out to the screen
that the user has logged out.
Event::subscribe('UserEventHandler');
class UserEventHandler {
Route::get('/', function()
{
// here is where the events fire
Event::fire('user.login');
Event::fire('user.newsletter');
Event::fire('user.logout');
});
Where to put Event Listeners
So this has been very helpful so far. We are setting up event listeners and taking action on
those events both with and without a dedicated class. We have been able to get this to
work in the routes file but that is not going to be a good place to put these listeners.
Following the Laravel File Structure examples, we’re going to create a
dedicated Handlers folder to hold all this stuff. The steps to set this up are as follows:
• 1: Create The Namespace
In this example we have a laratut namespace within our app folder. So
within laratut, we can now create a Handlers folder to hold our new class. Just
remember to have the psr-4 autoload registered in your composer.json so that
Laravel knows where these files live. For this example our snippet might look like
this "psr-4": { "laratut\": "app/laratut" } although yours might be different
depending on your namespace. If you’re not sure about your psr-4, check out
the Composer Autoloading Tutorial.
• 2: Create Event Handling Class
Within your new namespace, create the new class file. We name
ours UserEventHandler.php In this file, we just remove the class we had previously
defined on the routes file, and place it in this file. Do note however that you now need
to make a few namespace updates in this file, since it now lives in a different
namespace! Basically, you need to add your particular namespace at the top of the
file, as well as prepend the hardcoded controller methods with the namespace. In
this example the namespace is laratutHandlers so at the top of the file, we just
add namespace laratutHandlers; and prepend the namespace to the controllers like
you see here. Our updated file now looks like this:
UserEventHandler.php
<?php
namespace laratutHandlers;
class UserEventHandler {
• 3: Register Subscription
We still need to have a way to register the subscription so that we can listen for when
events get fired. Before we simply had our event subscription in our routes file and all
was good. Now that we have moved everything to a namespace, we’ll need to
include the namespace when passing the string to the subscribe method and if you
don’t want that cluttering up your routes file, you can simply move it
to app/start/global.php after the App::down() method like so:
<?php
App::down(function()
{
return Response::make("Be right back!", 503);
});
/*
|--------------------------------------------------------------------------
| Register Subscriptions
|--------------------------------------------------------------------------
*/
Event::subscribe('laratutHandlersUserEventHandler');
Route::get('/', function()
{
// here is where the events fire
Event::fire('user.login');
Event::fire('user.newsletter');
Event::fire('user.logout');
});
Awesome! When you visit the homepage now, everything still works, and you now have a
dedicated class where you can add as many listeners as you like to take action on fired
events. Lots of fun indeed!
Let’s take a moment to talk about cache. Now when we say cache, we’re not
talking about dollar bills, although that’s what it sounds like! Caching is the act
of transparently storing data for future use in an attempt to make applications
run faster. There are all kinds of ways to cache data, and Laravel makes it easy
to do so with just a small number of method calls. Once you have an application
up and running, you’ll be ready to tune it to perfection – and handling caching of
data is part of that process. Let’s jump in!
return array(
/*
|--------------------------------------------------------------------------
| Default Cache Driver
|--------------------------------------------------------------------------
|
| This option controls the default cache "driver" that will be used when
| using the Caching library. Of course, you may use other drivers any
| time you wish. This is the default when another is not specified.
|
| Supported: "file", "database", "apc", "memcached", "redis", "array"
|
*/
/*
|--------------------------------------------------------------------------
| File Cache Location
|--------------------------------------------------------------------------
|
| When using the "file" cache driver, we need a location where the cache
| files may be stored. A sensible default has been specified, but you
| are free to change it to any other place on disk that you desire.
|
*/
/*
|--------------------------------------------------------------------------
| Database Cache Connection
|--------------------------------------------------------------------------
|
| When using the "database" cache driver you may specify the connection
| that should be used to store the cached items. When this option is
| null the default database connection will be utilized for cache.
|
*/
/*
|--------------------------------------------------------------------------
| Database Cache Table
|--------------------------------------------------------------------------
|
| When using the "database" cache driver we need to know the table that
| should be used to store the cached items. A default table name has
| been provided but you're free to change it however you deem fit.
|
*/
/*
|--------------------------------------------------------------------------
| Memcached Servers
|--------------------------------------------------------------------------
|
| Now you may specify an array of your Memcached servers that should be
| used when utilizing the Memcached cache driver. All of the servers
| should contain a value for "host", "port", and "weight" options.
|
*/
),
/*
|--------------------------------------------------------------------------
| Cache Key Prefix
|--------------------------------------------------------------------------
|
| When utilizing a RAM based store such as APC or Memcached, there might
| be other applications utilizing the same cache. So, we'll specify a
| value to get prefixed to all our keys so we can avoid collisions.
|
*/
);
First off we can see that there are many options for how you actually want to handle
caching. In other words, you can choose which driver to use to handle cache. By default it
is set to file, however any of the following are supported: database, apc, memcached, redis,
and array.
Next up the path to where the cache data will be stored is specified. Out of the box your
cache data will be located at app/storage/cache and this will work fine for most scenarios.
The remaining configuration options deal with scenarios where you might be using a
database to store the cache data or a memcached option.
Cache::put()
The first method we’ll take a look at is the Cache::put() method. It takes three parameters
being a key, value, and time in minutes to cache the data. Let’s test it out by giving a key
of cachekey, a value of I am in the cache baby!, and a storage time of 1 minute:
Route::get('/', function()
{
Cache::put( 'cachekey', 'I am in the cache baby!', 1 );
});
Go ahead and load up your home page. Now if you we’re hoping for some really exciting
things to happen upon loading that route, I do apologize as you are probably just staring at
a blank white page. What this example did do for us though, is create some new cache
data in the app/storage/cachefolder. In our installation, it created a few subfolders and the
resulting data file looks something like 773d6310cb469462e79d0f7ff0a55840 within
the app/storage/cache folder. On opening that file, we can see the data that has been
cached: 1406759615s:23:”I am in the cache baby!”;
Cache::get()
Ok you’ve stored some data in the cache and you’re ready to retrieve it now instead of
bogging down your entire application. How can you fetch that data? It’s quite easy young
grasshopper. Just bust out your Cache::get() method and pass it the key of the cache you
are trying to retrieve like so:
Route::get('/', function()
{
return Cache::get( 'cachekey' );
});
Load up the home page and like magic, I am in the cache baby! is returned. Awesome! You
may have noticed that we only stored our data for 1 minute. That’s not very long. What
happens if we try to get data from the cache after it’s gone? Well in that case you can
provide a second parameter to the Cache::get() method so that a default value will be
provided. For example:
Route::get('/', function()
{
return Cache::get( 'cachekey', 'The cache is empty, so here is something to keep you happy' );
});
Let’s say you load up the homepage 30 seconds later. Well in that case, your cache data
is still there and you find I am in the cache baby!, however if you load the page a few
minutes later, the cache will then be expired. In that case our default value will be returned
of The cache is empty, so here is something to keep you happy.
Very nice implementation on Laravels part if I do say so myself. If you’ve ever had to build
a caching mechanism by hand in any of your non-framework applications, then you can
surely appreciate the simplicity of this approach.
Cache::forever()
This method is for storing data into the cache and you just want it to be available for the
user, without specifying a time for storage. That might look something like:
Route::get('/', function()
{
Cache::forever( 'cachekey', 'I am in the cache baby!' );
});
Cache::has()
This method is useful for checking to see if the cache has the key you’re looking for. It’s
almost like checking a database for an entry before returning it. With this approach, we can
check the cache to see if it has what we want, then return it like this:
Route::get('/', function()
{
if( Cache::has( 'cachekey' ) ) {
return Cache::get( 'cachekey' );
}
});
Cache::forget()
If you do decide to use Cache::forever(), it might be nice to have a way to remove that
key from the cache. You can do this with Cache::forget() like so:
Route::get('/', function()
{
Cache::forget( 'cachekey' );
});
So what happens here is, cachekey gets removed from the cache, the if finds
that cachekey is no longer there, and we are returned with the data cachekey was
forgotten, so this is just random data
Route::get('/', function()
{
$users = User::remember(1)->get();
In the code above we have added a special snippet so that we can view the queries that
eloquent creates for us. Anytime a database call is made, since we are listening
for illuminate.query, we will see the actual SQL. This is a fantastic feature, and works as
a way to profile your application.
Notice we are using the User model to get some data from the database. Notice
that remember()method we snuck right in there! This method takes a number value which
specifies the number of minutes to cache the result of your database query. In this
example we only cache it for a minute, but that is only so we can demonstrate how this
works. When we visit the homepage, if the database query is not cached, the SQL will be
displayed to the screen. If the query is cached, the data will simply be pulled from cache,
and you will not see the query. Notice how this works:
The second time the page loads, we see no SQL displayed. This means that data came
right from the cache instead of the database. Epic!
Route::get('/', function()
{
$users = User::remember(1)->get();
})->before('routename');
This small snippet first registers a filter by specifying the name of the filter, in this
case routename, and then a closure which accepts the parameters of $route, $request,
and $response. $route and $request are mandatory for before filters
while $route, $request, and $response are required for after filters. Inside the closure, you
can do whatever logic you like. In this case we’ll just return I come before the route
runs for demonstration purposes. We can trigger that filter by simply adding -
>before('routename') to the end of the route we want to apply it to. So in this case when
we now visit the homepage route, we’ll simply see I come before the route runs instead of
the data returned from the database.
Route::get('/', function()
{
$users = User::all();
})->before('cache.grab')->after('cache.set');
Notice that we chained both a before filter and an after filter to the home route by
adding ->before('cache.grab')->after('cache.set'). We left the event listener in
place to simply show us when we are getting data from the cache versus when we
are getting data which is generated on the fly for us. Recall that when data comes
from the cache, there will be no SQL dumped to the screen, whereas if there is a
database hit, we will see the SQL displayed. Also, notice the convention
of cache.grab and cache.set. We use the dot notation to remind us
that grab and set will be methods defined in a dedicated class and resolved out of
the IoC Container.
• 2: Register Filter Names with IoC Container
Now that we know we’d like to have a before filter of cache.grab and an after filter
of cache.set, we can configure our registration with the IoC. Open
up app/filters.php and add this code at the end of the file to do just that. Note, the
comments are also by us, so you can add those as well.
<?php
/*
|--------------------------------------------------------------------------
| User Defined Filters
|--------------------------------------------------------------------------
|
| These are user generated by you to use the IoC container to load
| your own Filter Class
|
*/
Route::filter( 'cache.grab', 'laratutFiltersCacheFilter@grab' );
Route::filter( 'cache.set', 'laratutFiltersCacheFilter@set' );
These two lines simply map our two new filter names to method calls within
the laratutFiltersnamespace in a CacheFilter class.
• 3: Create Your Cache Class
The last step so get this to work is to actually create the class that will do the work for
us. In our case, we create CacheFilter.php in the laratutFilters namespace. Note:
We had already had this namespace set up from a prior lesson, and composer
dump had already been run for this namespace. This means our files will autoload no
problem, but if you are creating this lesson from scratch, you may need to add the
namespace to your composer.json, and run composer dump.
CacheFilter.php
<?php
namespace laratutFilters;
use IlluminateRoutingRoute;
use IlluminateHttpRequest;
use IlluminateHttpResponse;
use Str;
use Cache;
class CacheFilter {
So how does this class work? Let’s examine the whole flow of this code and we’ll better
understand. When a user visits the home route, the cache.grab filter will be
called before the request is loaded. This will trigger the grab method in
the CacheFilter class. This method does the following:
At this point, if the page is coming from cache, it will simply display to the browser. On the
other hand, if the cache.grab does nothing since there was no key in the cache, Laravel
will do what it normally does when you visit a route. It will query the database, render a
view, filter view data, and so on. The user will get their expected result in the browser.
Once this process is done, the after filter of cache.setwill then trigger. This set method
does the following for us:
In addition to this, if we look in the app/storage/cache folder, we can find a file that does
contain the full HTML contents. This data was placed in cache by our set method.
1406820530s:814:"<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Laravel Cache Tutorial</title>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<div class="container">
<div>
<h1>Laravel Cache Tutorial</h1>
</div>
<div class="col-lg-8">
<h4 class="alert alert-success">vegibit@dbcache.com </h4>
</div>
<div class="col-lg-8">
<h4 class="alert alert-success">cache@get.com </h4>
</div>
</div>
</body>
</html>";
Filters are really a fantastic resource to use in Laravel. In fact, almost all
applications will use them in one way or another. Filters give you the ability to
tap into the routing lifecycle within Laravel and take actions based on various
conditions both before and after the route request and response. We also saw
in the last episode on Larvael Cache techniques, that we can combine the use
of filters and caching together. There are many useful things we can do with
Filters in Laravel, so let’s get right to it!
Right now, anyone can view this page as you can see here.
Route::get('login', function()
{
return View::make('login.index');
});
In this snippet above we do a couple things. Notice that we add the before() filter to the
admin route. In addition, we added a second route to the file of login. This is so we don’t
throw an exception once our auth filter kicks in to redirect any non authorized users back
to the login page. In a way it almost reads backwards as in, “Before I render this admin
area to you, I will run the auth filter to see if I should do this or not.” Now that we updated
our admin route to include an auth filter, check out what happens when we try to visit that
area of the website:
Nice!So how did this magic work? Well, like we said earlier, Laravel ships with some filters
already set up for you in app/filters.php. Let’s have a look at the code that provides this
functionality to us:
Route::filter('auth', function()
{
if (Auth::guest())
{
if (Request::ajax())
{
return Response::make('Unauthorized', 401);
}
else
{
return Redirect::guest('login');
}
}
});
What this code does for you is to simply check if the user is authorized, and send them on
their way if they are not. We can see that it has support for ajax as well, which is quite
slick. In our routes file we had referenced the filter by the name of ‘auth’ and we can see
here how to define that very filter using Route::filter(). The Redirect::guest() method
has the added benefit that once the user *is* logged in, they will be sent to whatever page
they had intended to visit by way of intended redirections.
Cross Site Request Forgery Attack Filer
The default Laravel installation also has a filter to deal with CSRF attacks. CSRF attacks
can lead to a user unknowingly sending HTTP requests to various websites to take actions
the user has no idea is happening. At it’s most benign, the user might like a facebook page
without actually realizing it. At the other end of the spectrum would be transferring money
out of an online account with no knowledge of it happening. So, it is important to make
sure you do put the CSRF filter to use. It’s code looks like this:
Route::filter('csrf', function()
{
if (Session::token() != Input::get('_token'))
{
throw new IlluminateSessionTokenMismatchException;
}
});
The application of a csrf filter is for routes that are going to process form data and you
would call it using before(). This is the reason the Laravel Form::open() method
generates a security token for you. That security token is used with this filter to eliminate
any possible csrf issues for the user by way of the Synchronizer Token Pattern.
App::after(function($request, $response)
{
//
});
These are the global filters, meaning you can set up logic inside each of these to run on
every single request in the application. They will no longer be attached to specific routes or
controllers. You can find some examples of how to use these in the documentation or on
sites like Laravel Recipes, Laravel Tricks, and so on.
Route::get('login', function()
{
return View::make('login.index');
});
Cool.So this approach works just the same, it’s just a different syntax. Now that we know
how to use this syntax, we can also make use of stacking filters. Now we are going to
create the most non sensical filters you have ever seen here. They will be useful for pretty
much nothing, other than showing us how the filters trigger and stack! I gave you fair
warning, do not put this into your code, but do feel free to test it out for fun to see how
filters get triggered!
Route::filter('two', function()
{
echo '<div class="alert alert-warning">Filter 2</div>';
});
Route::filter('three', function()
{
echo '<div class="alert alert-success">Filter 3</div>';
});
As you can see, these filters are not doing anything useful, but I promise they will help us
in understanding how we can attach them to routes! Now check out how we stack these in
our routes.php by separating filter names with a pipe.
Route::get('admin', array( 'before' => 'one:booey|two|three', function()
{
return View::make('admin.index');
}));
Now here is the deal partner. We no longer are using the auth filter, and we are instead
going to call these three filters in succession before the admin route. Now anyone will be
able to enter our administrative kingdom, and they’ll see some messages to confirm that
filters were firing along the way as well. Visit the admin route, and check it:
Oh yeah! BabaBooey! You see, we have made it to the admin area, and you can see that our
filters did trigger successfully.
Bird 1.
You see, it’s bugging me that we went and changed up our syntax for how we apply the
filter from chaining, to an array as the second argument to the route. We’re going back to
chaining here as you can see. The goal is to test the pipe separation method of applying
filters using the chain to see if it works via this method as well.
Bird 2.
The second bird on our radar is the fact that there is a parameter involved with filter one.
Now, keep in mind that if you want to pass an argument to the closure in a filter, it is
the third parameter to be passed! I found this out myself as my application continued to
puke all over itself when I was passing a parameter to the filter and I couldn’t figure out
why. So this is why you see both the route, the request, and our custom parameter in
the third position like so:
Route::filter('one', function($route, $request, $baba)
{
if ( $baba == 'booey' ) {
echo '<div class="alert alert-info">Filter 1</div>';
}
});
There are a few things to observe here. First off, it looks like these filters work just
Excellent!
as well in stacking whether we are using the array as the second parameter syntax or the
method chaining syntax. Also, notice that only the message from filter two and filter three
were triggered. Why is this? This is because when we changed one:booey to one:potato in
our routes file, filter one then noticed within it’s if clause that $baba was no longer equal
to booey, it was equal to potato. Therefore, the filter one message did not trigger.
Group Filters
These are really slick. Basically, you just wrap all the routes that you want to have
assigned a filter and, voila, you’re done. The syntax looks like this:
Route::group(array('before' => 'one:booey|two|three'), function()
{
Route::get('admin', function()
{
return View::make('admin.index');
});
Route::get('login', function()
{
return View::make('login.index');
});
});
So here, what we do is to take the same routes we’ve been working with so far, and just
wrap them within a Route group with the filter applied. Now when we visit these routes, our
three filters will be triggered. Let’s visit the login route just to be sure:
Excellent, we can see that, yes, the login route loads up just fine and we see at the top of
the page that all three filters did fire before the request. There are all kinds of ways to
define and apply filters, just have a look at the docs for the full comprehensive list.
Flash Container
First up, we need to consider where we are going to display the flash messages. Usually,
you can place a div as a placeholder right in a master page. Therefore, all of your actual
views will extend the master page, and will have access to the div so that flash messages
could easily be displayed anywhere in your application. Read up on Blade in Laravel if you
need a refresher on how to set up your master page.
This will be our master page which will hold our container:
default.blade.php
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Laravel Flash Message Tutorial</title>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<body>
<div class="container">
<div>
<h1>Laravel Flash Messages</h1>
</div>
@if ( Session::has('flash_message') )
@endif
@yield('content')
</div>
</body>
</html>
Session::flash()
There are a couple of ways to do this, but the first approach will make use
of Session::flash(). Ok, here is our little application so far:
routes.php
<?php
Route::get('/login', function()
{
// Log in the user, blah blah...
return Redirect::to('home');
});
Route::get('/edit', function()
{
// User can edit their profile here...
Session::flash('flash_message', '<b>Heads up!</b> You just made a cool edit to your profile.');
Session::flash('flash_type', 'alert-info');
return Redirect::to('home');
});
Route::get('/cancel', function()
{
// User can cancel their membership here...
return Redirect::to('home');
});
Route::get('/delete', function()
{
// User can delete their account here...
Session::flash('flash_message', '<b>Oh Snap!</b> Are you sure you want to delete your account?');
Session::flash('flash_type', 'alert-danger');
return Redirect::to('home');
});
Route::get('home', function()
{
Return View::make('home');
});
So what do we have here? Well, each route is an example of completing the action that
the name of the route infers, setting a flash message, and then redirecting the user back to
the home page.
All Views Inherit From default.blade.php
So we have our master page set up, which includes some links to external content delivery
networks to make it easy to have access to the twitter bootstrap classes we’ll use in this
episode. We also include an if clause to check if there is a flash message present so that
we will only display the message once. When will the flash message display? The flash
message will display only during the initial redirect to the home page. Once you start
reloading the home page, the flash session is cleared, and you will not see any message.
Here is our home view:
home.blade.php
@extends('layouts.default')
@section('content')
<div class="col-lg-8">
</div>
@stop
Edit Profile
http://localhost/laratut/public/edit
Cancel Membership
http://localhost/laratut/public/cancel
Delete Account
http://localhost/laratut/public/delete
Cool!Now anytime you click on the go home links, the home page will load and there will be
no flash message. This is because, the flash message is only for the initial page load.
return Redirect::to('home')
->with('flash_message', '<b>Well done!</b> You successfully logged in to this website.')
->with('flash_type', 'alert-success');
});
Route::get('/edit', function()
{
// User can edit their profile here...
return Redirect::to('home')
->with('flash_message', '<b>Heads up!</b> You just made a cool edit to your profile.')
->with('flash_type', 'alert-info');
});
Route::get('/cancel', function()
{
// User can cancel their membership here...
return Redirect::to('home')
->with('flash_message', '<b>Warning!</b> You are about to cancel your membership.')
->with('flash_type', 'alert-warning');
});
Route::get('/delete', function()
{
// User can delete their account here...
return Redirect::to('home')
->with('flash_message', '<b>Oh Snap!</b> Are you sure you want to delete your account?')
->with('flash_type', 'alert-danger');
});
Route::get('home', function()
{
Return View::make('home');
});
Testing out this new method of applying our flash data has the same effect. In addition,
when we visit or reload the home page, we can see that no message is displayed, just as
we intended.
The Flashing Takeaway
Do you have to use Flash Messages in your applications? Of course not, but they are a
really nice way to give guidance to the user during their navigation of your website or
application. Personally, I am a big fan of using Flash Messages. They did confuse me at
first, but now that we have crushed this tutorial together, working with Flash Messages in
Laravel couldn’t be easier!
In this episode we’re going to take a look at sending email from a Laravel
Application. There are a few ways to send email, but we’ll focus on using SMTP
or Simple Mail Transfer Protocol using the SendGrid Service. SMTP is an open
standard defined in RFC 821 which dates all the way back to 1982! It is the
most common way to send email on the Internet and makes use of TCP ports
25 and 587. SendGrid is one of the biggest EiaaS, email infrastructure as a
service provider. Some well known compaies making use of the SendGrid API
include Uber, Spotify, and Pinterst. With Laravel, it’s easy to tie in to a
SendGrid account and send email from our application as well. Let’s check it
out!
return array(
/*
|--------------------------------------------------------------------------
| Mail Driver
|--------------------------------------------------------------------------
|
| Laravel supports both SMTP and PHP's "mail" function as drivers for the
| sending of e-mail. You may specify which one you're using throughout
| your application here. By default, Laravel is setup for SMTP mail.
|
| Supported: "smtp", "mail", "sendmail", "mailgun", "mandrill", "log"
|
*/
/*
|--------------------------------------------------------------------------
| SMTP Host Address
|--------------------------------------------------------------------------
|
| Here you may provide the host address of the SMTP server used by your
| applications. A default option is provided that is compatible with
| the Mailgun mail service which will provide reliable deliveries.
|
*/
/*
|--------------------------------------------------------------------------
| SMTP Host Port
|--------------------------------------------------------------------------
|
| This is the SMTP port used by your application to deliver e-mails to
| users of the application. Like the host we have set this value to
| stay compatible with the Mailgun e-mail application by default.
|
*/
/*
|--------------------------------------------------------------------------
| Global "From" Address
|--------------------------------------------------------------------------
|
| You may wish for all e-mails sent by your application to be sent from
| the same address. Here, you may specify a name and address that is
| used globally for all e-mails that are sent by your application.
|
*/
/*
|--------------------------------------------------------------------------
| E-Mail Encryption Protocol
|--------------------------------------------------------------------------
|
| Here you may specify the encryption protocol that should be used when
| the application send e-mail messages. A sensible default using the
| transport layer security protocol should provide great security.
|
*/
/*
|--------------------------------------------------------------------------
| SMTP Server Username
|--------------------------------------------------------------------------
|
| If your SMTP server requires a username for authentication, you should
| set it here. This will get used to authenticate with your server on
| connection. You may also set the "password" value below this one.
|
*/
/*
|--------------------------------------------------------------------------
| SMTP Server Password
|--------------------------------------------------------------------------
|
| Here you may set the password required by your SMTP server to send out
| messages from your application. This will be given to the server on
| connection so that the application will be able to send messages.
|
*/
/*
|--------------------------------------------------------------------------
| Sendmail System Path
|--------------------------------------------------------------------------
|
| When using the "sendmail" driver to send e-mails, we will need to know
| the path to where Sendmail lives on this server. A default path has
| been provided here, which will work well on most of your systems.
|
*/
/*
|--------------------------------------------------------------------------
| Mail "Pretend"
|--------------------------------------------------------------------------
|
| When this option is enabled, e-mail will not actually be sent over the
| web and will instead be written to your application's logs files so
| you may inspect the message. This is great for local development.
|
*/
);
By reading the comments, you can see exactly what all of these configuration options are
used for. For the purposes of this demonstration, we’ll update four of the options. By
default the host key of the mail configuration array is set to smtp.mailgun.org. We are
going to swap that out for smtp.sendgrid.net as this is the address required when using
SendGrid. Next, we’ll update the from field. Here we can specify the address from where
our email will be sent from as well as setting the name. Last up, we’ll fill in the user name
and password of our SendGrid account. If you happen to be using a different SMTP
service provider, simply fill out your user name and password here, and it should be just as
easy to get this configured and ready to send email.
Send an Email
After we have set up just a small array of configuration options, we’re ready to try to send
an email with Laravel. We’ll add a sendmail route to our routes file like so:
<?php
Route::get('/sendmail', function()
{
$data = array('name' => 'Jordan');
In the snippet above, we have a few things to take note of. The main idea is
that Mail::send() is the method we are interested in, but let’s take a look at the parameters
that are passed to the method.
First Parameter: The first parameter that gets passed to the Mail::send() method is the
view to be used for the email message. For example, your app may have a welcome email
template, and possibly all kinds of other notification email templates. If you are familiar with
Twitter, you’ll know that by default, they email you for almost anything and everything
possible. If someone follows you, send an email to you. If someone mentions you, send an
email. A new feature came out, send you an email. If you’re like me, you go and disable all
of these notifications, but the idea here is that each scenario may represent a different
template for the email that will get sent. In our case, we’re just going to send a welcome
email.
Second Parameter: The second parameter is the data which will get passed to the view.
Most times when we send an email, it would be nice to specify the user’s name so we can
address them properly when we send the email. We’ll pretend the user’s name is Jordan
so we can say hi when we send the welcome email.
Third Parameter: The third parameter to be passed to the Mail::send() method is a PHP
Closure which specifies the various options available for sending the email. This Closure
accepts a $message instance which makes use of the SwiftMailer message class, so it
pays to be familiar with how SwiftMailer works by checking out their documentation. Of
course the official Laravel Documentation will be your friend here as well.
Here is the view that we will use for our welcome email.
welcome.blade.php
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Mailer Demo</title>
</head>
<body>
Hi {{ $name }},
<br>
Welcome to the Laravel and SendGrid SMTP tutorial. This email was sent from Laravel using
SendGrid as a service.
<br>
Best Regards
</body>
</html>
Send an Email!
Ok I think we’re ready to try to send an email. All we have to do is visit the sendmail route
we specified. When visiting http://vegi.bit/sendmail in the local development
environment, we’ll notice a small pause, then simply a white screen. Let’s go check our
accounts and see if the mail was sent.
Looks like the message is in our inbox, when we click it, we can see the message as well.
Conclusion
This was a quick overview of how to send an email using the great Laravel PHP
framework. Now that we have this simple example down, it would make sense to dig in to
the mailer pattern, mail queues, mail pretend, and many other great features of working
with email in Laravel. Those will be topics for different episodes, but at least we have the
basics under our belt to build upon further.
'IlluminateFoundationProvidersArtisanServiceProvider',
'IlluminateAuthAuthServiceProvider',
'IlluminateCacheCacheServiceProvider',
'IlluminateSessionCommandsServiceProvider',
'IlluminateFoundationProvidersConsoleSupportServiceProvider',
'IlluminateRoutingControllerServiceProvider',
'IlluminateCookieCookieServiceProvider',
'IlluminateDatabaseDatabaseServiceProvider',
'IlluminateEncryptionEncryptionServiceProvider',
'IlluminateFilesystemFilesystemServiceProvider',
'IlluminateHashingHashServiceProvider',
'IlluminateHtmlHtmlServiceProvider',
'IlluminateLogLogServiceProvider',
'IlluminateMailMailServiceProvider',
'IlluminateDatabaseMigrationServiceProvider',
'IlluminatePaginationPaginationServiceProvider',
'IlluminateQueueQueueServiceProvider',
'IlluminateRedisRedisServiceProvider',
'IlluminateRemoteRemoteServiceProvider',
'IlluminateAuthRemindersReminderServiceProvider',
'IlluminateDatabaseSeedServiceProvider',
'IlluminateSessionSessionServiceProvider',
'IlluminateTranslationTranslationServiceProvider',
'IlluminateValidationValidationServiceProvider',
'IlluminateViewViewServiceProvider',
'IlluminateWorkbenchWorkbenchServiceProvider',
'WayGeneratorsGeneratorsServiceProvider',
'ThujohnTwitterTwitterServiceProvider',
),
),
return array(
'API_URL' => 'api.twitter.com',
'API_VERSION' => '1.1',
'USE_SSL' => true,
Note that these are the API key, API secret, Access token, and Access token
secret you have listed in your app at the developer console on Twitter. Fill in these values
with your own here in this config file.
Send a Tweet!
All of the legwork is now out of the way. We can take our new Laravel Twitter Application
for a spin! We’ll start with the obligatory example from the routes file like so:
<?php
Route::get('/tweet', function()
{
return Twitter::postTweet(array('status' => 'Tweet sent using Laravel and the Twitter API!',
'format' => 'json'));
});
Now, if we’ve done everything correctly, as soon as we hit that route, a tweet will be sent
to Twitter with the status of “Tweet sent using Laravel and the Twitter API!” Let’s try.
Awesome!As you can see, it worked like a charm – with link direct to the tweet which was
posted
Route::get('/getmytweets', function()
{
$tweets = Twitter::getUserTimeline(array('screen_name' => 'vegibit', 'count' => 20, 'format' =>
'object'));
foreach($tweets as $tweet){
echo '<b>Tweet Text:</b> '.Twitter::linkify($tweet->text).'<br>';
echo '<strong>Posted By:</strong> <a href="http:'.Twitter::linkUser($tweet->user).
'">'.$tweet->user->name.'</a> <em>'.Twitter::ago($tweet->created_at).'</em><br>';
echo '<strong>Original Tweet:</strong> <a href="http:'.Twitter::linkTweet($tweet).
'">http:'.Twitter::linkTweet($tweet).'</a><hr>';
}
});
Tweet Text: Tweet sent using Laravel and the Twitter API!
Posted By: vegibit 1 hour ago
Original Tweet: http://twitter.com/vegibit/status/501400060983140352
Tweet Text: The Top 9 Most Important HTML Form Concepts You Should
Master http://t.co/aqw4y2JuEP#html #webdevelopment
Posted By: vegibit 1 day ago
Original Tweet: http://twitter.com/vegibit/status/501052135354953729
Tweet Text: Top 12 Websites for Twitter Bootstrap http://t.co/1kZg5ksZy5
Posted By: vegibit 1 day ago
Original Tweet: http://twitter.com/vegibit/status/501040545011998723
Tweet Text: This Is How To Make AJAX Awesome With jQuery http://t.co/SOh2x8PoTE
Posted By: vegibit 1 day ago
Original Tweet: http://twitter.com/vegibit/status/501040206070308864
Conclusion
Using Laravel to work with the Twitter API is pretty easy when you make use of the great
libraries the community has come up with. This particular one seems to be just perfect,
and feels like a direct extension of Laravel as everything is done in a Facade style. It really
makes working with the Twitter API in Laravel a breeze. When you’re ready for a bigger
challenge using this library, check out this tutorial done by Creative Punch, it’s fantastic!
In the last episode we built a bare bones regular expression tester using PHP. It
does what we need it to, but its really limited, and doesn’t look that great. In this
episode, we are going to Larafy it. We’re going to re build the regular
expression tester using Laravel. This should be a good test of hacking
something quick and dirty together using native PHP versus building it in a
framework like Laravel. The two approaches are really different, and this little
exercise will give us a good idea of how to change up our thinking. Let’s check
it out.
Laravel 4.2
For this example, we’re going to make use of Laravel 4.2. Though we’re all looking forward
to Laravel 5 and all of the cool new features it has – it still is a moving target as things
change so we’ll stick with Laravel 4.2 for now. We’re going to mimic what we did in the first
iteration of this project without a framework. This is the first iteration with Laravel, and I’m
taking the approach of simply, get something working, then worry about refactoring later.
So that is what we’ll do.
routes.php
<?php
Route::get('/', function () {
$result = Session::get('result');
$message = Session::get('message');
return View::make('regex')->with(['result' => $result, 'message' => $message]);
});
Route::post('regex', function () {
$data = Input::all();
$subject = $data['subject'];
$pattern = $data['pattern'];
try {
preg_match_all('/' . $pattern . '/', $subject, $matches);
} catch (Exception $e) {
return Redirect::to('/')->withInput()->with('message', $e->getMessage());
}
if (sizeof($matches[0]) > 0) {
foreach ($matches[0] as $match) {
$result[] = $match;
}
Session::flash('result', $result);
} else {
Session::flash('message', 'There were no matches');
}
return Redirect::to('/')->withInput();
});
master.blade.php
<!doctype html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css">
<script src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
<meta charset="utf-8">
<title>Regex Test</title>
</head>
<body>
<div class="container">
<div>
<h1>Laravel Regex Tester</h1>
</html>
regex.blade.php
@extends('layouts.master')
@section('content')
{{ Form::open( ['url' => 'regex'] ) }}
{{ Form::close() }}
@if(sizeof($result[0]) > 0)
<div class="alert alert-success">Here are your matches</div>
@foreach( $result as $match )
{{ $match }} <br>
@endforeach
@elseif($message)
@if(strstr($message,'Here are your matches'))
<div class="alert alert-info"> {{ $message }} </div>
@else
<div class="alert alert-danger"> {{ $message }} </div>
@endif
@endif
@stop
Conclusion
This was a fun little test of hacking together a quick and dirty regular expression tester in
Laravel. We made use of basic routes, Laravel Blade templating, Laravel Validation, and
some good old fashioned native PHP to accomplish our goal. Thanks for checking it out.
<?php
use thedomainrepositoriesregexrepositoryRegexRepositoryInterface;
use thedomainrepositoriesvalidationrepositoryValidationRepositoryInterface;
if ($haserrors) {
return Redirect::to('/regex2')->withInput()->withErrors($haserrors);
} else {
$result = $this->regex->match($data['subject'], $data['pattern']);
return Redirect::to('/regex2')->withInput()->with(['result' => $result]);
}
}
}
laravelapproutes.php source
<?php
Route::get('/regex2', 'RegexController@index');
Route::post('/processregex2', 'RegexController@match');
laravelappviewsregex.blade.php source
@extends('layouts.master')
@section('content')
{{ Form::open( ['url' => '/processregex2'] ) }}
{{ Form::close() }}
@if(is_array($result))
@if(count($result) > 0 )
<div class="alert alert-success">Here are your matches</div>
@foreach( $result as $match )
{{ $match }} <br>
@endforeach
@else
<div class="alert alert-info">Sorry No Matches</div>
@endif
@elseif(is_string($result))
<div class="alert alert-danger"> {{ $result }} </div>
@endif
@stop
laravelappviewslayoutsmaster.blade.php source
<!doctype html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css">
<script src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
<meta charset="utf-8">
<title>Regex Test</title>
</head>
<body>
<div class="container">
<div>
<h1>Laravel Regex Tester</h1>
</html>
Cool! The above files are pretty much the whole application (minus the plumbing
underneath), but this gives an idea of how to better layout the application design. Our first
attempt, thought it works, is a hackish mess. With this iteration, we have one fairly clean
controller, a couple of lines in the routes file, and a couple of views. The actual functionality
of the app is exactly the same. It just shows how problems can be solved with *very*
different approaches (You just want to gravitate towards the approaches that will keep you
sane).
The Supporting Cast
Thanks to Laracasts and Jeffrey Way, the Laravel and PHP Community as a whole has a
fantastic resource for learning about advanced application design and programming best
practices. I just wanted to give a shout out where credit is due, as this pattern here is
inspired by Jeff’s teachings.
Since we’re going to be applying the repository pattern, we’ll follow roughly the steps
outlined in an earlier post about repositories. This is the outline we’ll follow. It’s just slightly
modified from our prior version to make sure we are covering all steps.
<?php
namespace thedomainrepositoriesregexrepository;
interface RegexRepositoryInterface
{
public function match($subject, $pattern);
}
thedomainrepositoriesvalidationrepositoryValidationRepositoryInterface.php source
<?php
namespace thedomainrepositoriesvalidationrepository;
interface ValidationRepositoryInterface
{
public function haserrors($data, $rules);
}
<?php
namespace thedomainrepositoriesregexrepository;
use Exception;
$result = array();
if (sizeof($matches[0]) > 0) {
foreach ($matches[0] as $match) {
$result[] = $match;
}
}
return $result;
}
}
thedomainrepositoriesvalidationrepositoryValidtionRepository.php source
<?php
namespace thedomainrepositoriesvalidationrepository;
use Validator;
<?php
namespace thedomainrepositoriesregexrepository;
use IlluminateSupportServiceProvider;
thedomainrepositoriesvalidationrepositoryBackendServiceProvider.php source
<?php
namespace thedomainrepositoriesvalidationrepository;
use IlluminateSupportServiceProvider;
'IlluminateFoundationProvidersArtisanServiceProvider',
'IlluminateAuthAuthServiceProvider',
'IlluminateCacheCacheServiceProvider',
'IlluminateSessionCommandsServiceProvider',
'IlluminateFoundationProvidersConsoleSupportServiceProvider',
'IlluminateRoutingControllerServiceProvider',
'IlluminateCookieCookieServiceProvider',
'IlluminateDatabaseDatabaseServiceProvider',
'IlluminateEncryptionEncryptionServiceProvider',
'IlluminateFilesystemFilesystemServiceProvider',
'IlluminateHashingHashServiceProvider',
'IlluminateHtmlHtmlServiceProvider',
'IlluminateLogLogServiceProvider',
'IlluminateMailMailServiceProvider',
'IlluminateDatabaseMigrationServiceProvider',
'IlluminatePaginationPaginationServiceProvider',
'IlluminateQueueQueueServiceProvider',
'IlluminateRedisRedisServiceProvider',
'IlluminateRemoteRemoteServiceProvider',
'IlluminateAuthRemindersReminderServiceProvider',
'IlluminateDatabaseSeedServiceProvider',
'IlluminateSessionSessionServiceProvider',
'IlluminateTranslationTranslationServiceProvider',
'IlluminateValidationValidationServiceProvider',
'IlluminateViewViewServiceProvider',
'IlluminateWorkbenchWorkbenchServiceProvider',
'thedomainrepositoriesregexrepositoryBackendServiceProvider',
'thedomainrepositoriesvalidationrepositoryBackendServiceProvider'
),
"autoload": {
"classmap": [
"app/commands",
"app/controllers",
"app/models",
"app/database/migrations",
"app/database/seeds",
"app/tests/TestCase.php"
],
"psr-4": {
"thedomain\": "app/thedomain"
}
}
So Does It Work?
Great question, let’s find out!
Populate the providers array with the entry for Illuminate HTML.
Collective\Html\HtmlServiceProvider::class,
Configure the aliases array to allow for HTML and Form Facades.
'Form' => Collective\Html\FormFacade::class,
'Html' => Collective\Html\HtmlFacade::class,
@section('content')
<div class="well">
<fieldset>
<legend>Legend</legend>
</div>
<div class="radio">
{!! Form::label('radio2', 'This is option 2.') !!}
{!! Form::radio('radio', 'option2', false, ['id' => 'radio2']) !!}
</div>
</div>
</div>
</fieldset>
</div>
This is a good looking form. If you’re used to creating the form manually, the
Excellent.
snippets here can be used for a quick reference for the various form elements you may
need to create with blade.
The Master Layout
In the snippet above, we can see that it extends he master layout file. It makes sense to
include assets that you’ll need on many pages in the master layout such as bootstrap or
other related classes. This is the master layout we used for this example.
<!doctype html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css">
<script src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
<meta charset="utf-8">
<title>Laravel</title>
</head>
<body>
<div class="container">
<div class="row">
<div class="col-lg-8"> @yield('content') </div>
</div>
</div>
</body>
</html>
print_r($formdata);
This is fantastic stuff, let’s go through each form element in turn to see how to create it,
and how to fetch the data.
Form::open()
Laravel provides a convenient way to define a form in your views
using Form::open() and Form::close(). This section deals with how to open a form,
provide a route to which the form will be processed, and a class to style the form. In this
case the style comes from twitter bootstrap.
How to create in the view
{!! Form::open(['url' => '/processform', 'class' => 'form-horizontal']) !!}
Form::email()
The first form element in our example is an email field. Here is the markup used to create
the email form element.
How to create in the view
<!-- Email -->
<div class="form-group">
{!! Form::label('email', 'Email:', ['class' => 'col-lg-2 control-label']) !!}
<div class="col-lg-10">
{!! Form::email('email', $value = null, ['class' => 'form-control', 'placeholder' =>
'email']) !!}
</div>
</div>
Form::password()
The password field is the second form element we created with Laravel in our example
form.
How to create in the view
<!-- Password -->
<div class="form-group">
{!! Form::label('password', 'Password:', ['class' => 'col-lg-2 control-label']) !!}
<div class="col-lg-10">
{!! Form::password('password',['class' => 'form-control', 'placeholder' =>
'Password', 'type' => 'password']) !!}
</div>
</div>
Form::checkbox()
The checkbox field can be useful for getting answers to a yes or no question from the
user.
How to create in the view
<div class="checkbox">
{!! Form::label('checkbox', 'Checkbox') !!}
{!! Form::checkbox('checkbox') !!}
</div>
Form::textarea()
Your users can submit long form text with the textarea field. Here is how we do it in
Laravel.
How to create in the view
<!-- Text Area -->
<div class="form-group">
{!! Form::label('textarea', 'Textarea', ['class' => 'col-lg-2 control-label']) !!}
<div class="col-lg-10">
{!! Form::textarea('textarea', $value = null, ['class' => 'form-control', 'rows' =>
3]) !!}
<span class="help-block">A longer block of help text that breaks onto a new line and
may extend beyond one line.</span>
</div>
</div>
</div>
<div class="radio">
{!! Form::label('radio2', 'This is option 2.') !!}
{!! Form::radio('radio', 'option2', false, ['id' => 'radio2']) !!}
</div>
</div>
</div>
Form::select()
The drop down select element is in wide use across all kinds of applications today. This is
great for choosing a category, or size as in this example.
How to create in the view
<!-- Select With One Default -->
<div class="form-group">
{!! Form::label('select', 'Select w/Default', ['class' => 'col-lg-2 control-label'] )
!!}
<div class="col-lg-10">
{!! Form::select('select', ['S' => 'Small', 'L' => 'Large', 'XL' => 'Extra Large',
'2XL' => '2X Large'], 'S', ['class' => 'form-control' ]) !!}
</div>
</div>
How to fetch in your controller
$formdata = Input::all();
echo $formdata['select']; // XL
$multi = Input::get('multipleselect');
var_dump($multi);
// array (size=2)
// 0 => string 'honda' (length=5)
// 1 => string 'subaru' (length=6)
Form::submit()
All of these form elements are not going to be of much value to us unless we are able to
actually submit them for processing. This is how we accomplish that.
How to create in the view
<!-- Submit Button -->
<div class="form-group">
<div class="col-lg-10 col-lg-offset-2">
{!! Form::submit('Submit', ['class' => 'btn btn-lg btn-info pull-right'] ) !!}
</div>
</div>
Form::close()
Finally, we can easily close our form using Laravel’s Form::close() method.
More Resources
• http://blog.stidges.com/
• https://github.com/
• http://packalyst.com/
• https://packagist.org/
Conclusion
This was a fun post that highlights the specifics of creating, and processing data with forms
in Laravel. We did not cover validation, but that is ok since there are other posts here and
elsewhere that give great examples of how to do that. Instead, this episode can serve as a
cheat sheet or quick reference so to speak for how to both create the element on the view
side, and retrieve that data on the controller side.
init.sh
First up is the init.sh file. This file contains the following contents:
#!/usr/bin/env bash
mkdir -p ~/.homestead
cp src/stubs/Homestead.yaml ~/.homestead/Homestead.yaml
cp src/stubs/after.sh ~/.homestead/after.sh
cp src/stubs/aliases ~/.homestead/aliases
Soon we will run this script so by looking at the contents, we can understand what it does.
The first potential gotcha is the tilde character convention. If you look at the line mkdir -p
~/.homestead and say, “what the heck is that going to do?”, this is your answer. In
windows the ~/ combination equates to C:/Users/{yourname} so after we run this
command, we should have a folder located at something
like C:/Users/{yourname}/.homestead. The next 3 lines simply copy the files
from C:/homestead/src/stubsinto C:/Users/{yourname}/.homestead.
Vagrantfile
This file contains the following contents:
require 'json'
require 'yaml'
VAGRANTFILE_API_VERSION = "2"
homesteadYamlPath = File.expand_path("~/.homestead/Homestead.yaml")
afterScriptPath = File.expand_path("~/.homestead/after.sh")
aliasesPath = File.expand_path("~/.homestead/aliases")
require_relative 'scripts/homestead.rb'
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
if File.exists? aliasesPath then
config.vm.provision "file", source: aliasesPath, destination: "~/.bash_aliases"
end
Homestead.configure(config, YAML::load(File.read(homesteadYamlPath)))
| .. o+o|
| .o.++*|
| . . =++*|
| . o .. +o|
| S. . |
| o.E |
| o. |
| |
0| |
1 +-----------------+
8. Configure Windows hosts file
This step takes care of the ability to create nice short domain names that will route to your
development machine in the browser. The example we have followed so far is the
convention of using homestead.app just like the official docs do, so we’ll set that up now.
Understand that homestead.app is the actual domain name you type into your browser
when you’re ready to test. So if everything goes well, by the time we finish this whole
process, when we load http://homestead.app in a web browser, we’ll see our new Laravel
installation working.
Make sure to open notepad.exe as administrator, then navigate
to C:/Windows/System32/drivers/etc/hosts and add this 192.168.10.10 homestead.app to
the file right at the end.
# Copyright (c) 1993-2009 Microsoft Corp.
#
# This is a sample HOSTS file used by Microsoft TCP/IP for Windows.
#
# This file contains the mappings of IP addresses to host names. Each
# entry should be kept on an individual line. The IP address should
# be placed in the first column followed by the corresponding host name.
# The IP address and the host name should be separated by at least one
# space.
#
# Additionally, comments (such as these) may be inserted on individual
# lines or following the machine name denoted by a '#' symbol.
#
# For example:
#
# 102.54.94.97 rhino.acme.com # source server
# 38.25.63.10 x.acme.com # x client host
127.0.0.1 localhost
192.168.10.10 homestead.app
9. Configure Homestead.yaml
We are now ready to configure the Homestead.yaml configuration file. Recall that Vagrant
is going to be looking for this file
in C:/Users/{yourname}/.homestead/Homestead.yaml so this is the file to open and edit.
Original Homestead.yaml
ip: "192.168.10.10"
memory: 2048
cpus: 1
authorize: ~/.ssh/id_rsa.pub
keys:
- ~/.ssh/id_rsa
folders:
- map: ~/Code
to: /home/vagrant/Code
sites:
- map: homestead.app
to: /home/vagrant/Code/Laravel/public
databases:
- homestead
variables:
- key: APP_ENV
value: local
Modified Homestead.yaml
ip: "192.168.10.10"
memory: 2048
cpus: 1
authorize: ~/.ssh/id_rsa.pub
keys:
- ~/.ssh/id_rsa
folders:
- map: C:/localdev
to: /home/vagrant/Code
sites:
- map: homestead.app
to: /home/vagrant/Code/Laravel/public
databases:
- homestead
variables:
- key: APP_ENV
value: local
This step is pretty important and there has been a fair amount of confusion as to how this
works so we’ll drill right down here.
Folders
Notice that the only thing we changed is the map location in the folders: property. We are
now telling Vagrant that we have a bunch of files and folders in C:/localdev on the Local
Machine, and we want to automatically and instantly sync those files and folders
to /home/vagrant/Code on the Virtual Machine.
Sites
This handles mapping our domain name to the folder which contains the site we want to
load. So what the config file says here is that when we type homestead.app into the
browser, this will map to /home/vagrant/Code/Laravel/public on the Virtual Machine.
Since we had created a local Laravel project named Laravel in step 6, this all maps out
perfectly. The reason is that as soon as the Virtual Machine boots, it is going to look
in C:/localdev and see that there is a folder in it named Laravel. It will then instantly sync
all files and folders, so the Virtual Machine will now also contain a folder named Laravel in
it’s /home/vagrant/Code directory.
Introduction To Laravel 5
Laravel 5 is now officially available, and this Introduction To Laravel 5 will get
us started with it. So Why Laravel? Well, technology moves pretty fast and its
tough to keep up. Not only is it tough to keep up, but it is increasingly complex.
Laravel strives to make moving forward with Web Development simple, and
who doesn’t want simplicity? It is this unique combination of staying on the
cutting edge of web based development with modern PHP, while also keeping
things simple, that makes Laravel so attractive. It is with great excitement that
we dive into a new Laravel series here, and learn all about Laravel and what it
can offer us today.
Introduction To Laravel 5
\app\Http\routes.php source
<?php
/*
|--------------------------------------------------------------------------
| Application Routes
|--------------------------------------------------------------------------
|
| Here is where you can register all of the routes for an application.
| It's a breeze. Simply tell Laravel the URIs it should respond to
| and give it the controller to call when that URI is requested.
|
*/
Route::get('/', 'WelcomeController@index');
Route::get('home', 'HomeController@index');
Route::controllers([
'auth' => 'Auth\AuthController',
'password' => 'Auth\PasswordController',
]);
Depending on your level of experience working with Laravel, these existing routes may or
may not look familiar to you. It is the first route which actually loads the splash page of the
base install of Laravel. So how does this work? Without getting too far into the magic under
the hood, it is safe to read it like so. When a web request is made of /, or the homepage,
fire the index method of the WelcomeController. Let’s have a look at that now.
App\Http\Controllers\WelcomeController.php source
<?php namespace App\Http\Controllers;
/*
|--------------------------------------------------------------------------
| Welcome Controller
|--------------------------------------------------------------------------
|
| This controller renders the "marketing page" for the application and
| is configured to only allow guests. Like most of the other sample
| controllers, you are free to modify or remove it as you desire.
|
*/
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('guest');
}
/**
* Show the application welcome screen to the user.
*
* @return Response
*/
public function index()
{
return view('welcome');
}
Likewise to the routes file in the prior section, this is the default controller included with
Laravel when you first install it. Ok, so we are in the WelcomeController, and there is that
index method we were talking about. So what does it do? It looks like it simply calls a
function named view, and passes in the string of welcome. Pretty Slick! Now, this is a bit of
a change from prior versions of Laravel when you were required to use something
like View::make() to render a view. In any event, think of this like saying, display a
webpage named welcome. So what is the string welcome referring to? Let’s find out here.
\resources\views\welcome.blade.php source
<html>
<head>
<link href='//fonts.googleapis.com/css?family=Lato:100' rel='stylesheet' type='text/css'>
<style>
body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
color: #B0BEC5;
display: table;
font-weight: 100;
font-family: 'Lato';
}
.container {
text-align: center;
display: table-cell;
vertical-align: middle;
}
.content {
text-align: center;
display: inline-block;
}
.title {
font-size: 96px;
margin-bottom: 40px;
}
.quote {
font-size: 24px;
}
</style>
</head>
<body>
<div class="container">
<div class="content">
<div class="title">Laravel 5</div>
<div class="quote">{{ Inspiring::quote() }}</div>
</div>
</div>
</body>
</html>
Now this is interesting. Note that this particular file is the first one that is not part of
the \app directory. Why is that? Is it that views are some kind of second class citizen? Of
course not! Views are important in that they are what hold the data to display to our users.
Views are more like basic containers however used to only hold and display, and as such,
they don’t really fit in with the logic of our app. They are an important resource however, so
alas, they are contained within the resources folder. So how does this view work? Well,
note that all we had to do was pass welcome to the view() function, and Laravel knows to
map that to welcome.blade.php in the resources folder. You see how the convention works
I’m sure. Now you probably see the html and css and find it all quite easy to decipher.
What about the part where it comes to that {{ Inspiring::quote() }} ? You can consider
that your first use of blade. The double curly braces tell blade, that whatever comes in
between us, evaluate the code and provide the output. Cool! So it looks like this is
somehow referencing an Inspiring class and a quote method. Let’s see how this works as
well.
\vendor\laravel\framework\Illuminate\Foundation\Inspiring.php source
<?php namespace Illuminate\Foundation;
use Illuminate\Support\Collection;
class Inspiring {
/**
* Get an inspiring quote.
*
* Taylor & Dayle made this commit from Jungfraujoch. (11,333 ft.)
*
* @return string
*/
public static function quote()
{
return Collection::make([
])->random();
}
Not only does Laravel provide fantastic features and power, it can also provide
Excellent!
you with all the Inspiration you’ll ever need. If you don’t like the inspiration it provides, you
can even hack together your own inspiration. It might look something like this.
<?php namespace Illuminate\Foundation;
use Illuminate\Support\Collection;
class Inspiring {
/**
* Get an inspiring quote.
*
* Taylor & Dayle made this commit from Jungfraujoch. (11,333 ft.)
*
* @return string
*/
public static function quote()
{
return Collection::make([
'Eat Pizza with great vigor and tenacity, no matter the resistance.',
'Some would say nothing is impossible - not true, I do nothing all the time',
'I tried to be normal once. Worst experience I ever had.',
'Coffee. Our Love knows no bounds.',
'Putting the pro in procrastinate since... ah, do it tomorrow',
])->random();
}
There may be different inspirations for different people, so it’s fantastic that we can hack
our inspiration! When we test it out live on our homestead server, we can see the fruits of
our hacking right away.
use Illuminate\Http\Request;
Note that we still need to create the index method on our own, and we did so as you can
see. The make command did however create all the initial boilerplate, and took care of
setting up our namespaces for us, which is really nice.
Success!
Creating A Dynamic Laravel Web Page
We have completed creating a static web page in Laravel. Maybe you have a project that
will require 50 or 100 static web pages. You have the basic process down, so just follow
those steps and build from there. Now we’re going to take a look at creating dynamic web
pages with Laravel. This means, we will no longer hard code data into the view files, but
rather pass dynamic data to them, and present them that way. Let’s see how we can do
that. We are going to keep the same route, controller, and view. We will just update the
code in them to demonstrate how this works.
use App\Http\Requests;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
\resources\views\helloworld.blade.php source
{{ $variableone }}
http://homestead.app/helloworld
It seems to be working just fine. Note that even though we only passed one variable
Great!
value, it was still done so via an array. The second argument of the view() function must
be an array, no matter the number of values you are trying to pass. With that in mind, let’s
pass two values now.
\App\Http\Controllers\HelloWorldController.php source
<?php namespace App\Http\Controllers;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
\resources\views\helloworld.blade.php source
{{ $variableone }} {{ $variabletwo }}
http://homestead.app/helloworld
Nice.Note that you can keep adding as many keys to the array as you need. If you have 15
variables you need to pass, create 15 keys in the array and populate with your 15 values.
The Laravel with() Method
Laravel provides a really nice way to pass variables to view files using the with() method.
Instead of passing an array as the second argument to the view() function, we can chain
the with() method onto the view() call. This is one of those more modern ways to do
things, and it makes for really nice code readability. Let’s check it out.
\App\Http\Controllers\HelloWorldController.php source
<?php namespace App\Http\Controllers;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
\resources\views\helloworld.blade.php source
{{ $variableone }}
http://homestead.app/helloworld
Are you limited to passing only one variable to the view when using the with() method? Of
course not. Just pass an array to that sucker and watch yourself profit.
\App\Http\Controllers\HelloWorldController.php source
<?php namespace App\Http\Controllers;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
\resources\views\helloworld.blade.php source
{{ $variableone }} {{ $variabletwo }}
http://homestead.app/helloworld
We can also combine the idea of building up an array before rendering the view, and then
passing the data using the with() method. Let’s see how to do that here.
\App\Http\Controllers\HelloWorldController.php source
<?php namespace App\Http\Controllers;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
return view('helloworld')->with($data);
}
\resources\views\helloworld.blade.php source
{{ $variableone }} {{ $variabletwo }} {{ $variablethree }}
http://homestead.app/helloworld
<body>
<div class="container">
@yield('content')
</div>
</body>
</html>
Let’s note a few things here. Thanks to PHP Storm, we are able to quickly format
Excellent.
the source so that everything gets indented nicely and so on. The ctrl + alt + L key
combination are what we need for this. Next, since there is no possible way I can
remember all the classes available in bootstrap, (or method calls in Laravel for that
matter), PHP Storm saves the day with simply superb auto complete functionality. Being
able to start typing, and then seeing all of your available options is really fantastic. Working
with the Blade Master Template really becomes a joy in this way.
@section('content')
<div class="jumbotron">
<h1>{{ $variableone }}</h1>
@endsection
This is a good example of how named sections work. In our master page we yield a
section called content. In our view file that extends the master page then, we need a way
to name the content we are referring to. We do this with
the @section and @endsection keywords. Note that the @section keyword must also
have an associated name. In this case it is @section('content'). Basically, anything that
comes between these two keywords, is the content that gets injected
at @yield('content') in the master page. We can say then that @section /
@endsection define the content, and @yield makes use of it.
\resources\views\master.blade.php source
<html>
<head>
<!-- Latest compiled and minified jquery -->
<script src="https://code.jquery.com/jquery-2.1.3.min.js"></script>
<body>
<div class="container">
@include('navigation')
@yield('content')
@include('footer')
</div>
</body>
</html>
\resources\views\navigation.blade.php source
<nav class="navbar navbar-default">
<div class="container-fluid">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse"
data-target="#bs-example-navbar-collapse-1">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">{{ $brand }}</a>
</div>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-
expanded="false">Dropdown
<span class="caret"></span></a>
<ul class="dropdown-menu" role="menu">
<li><a href="#">Action</a></li>
<li><a href="#">Another action</a></li>
<li><a href="#">Something else here</a></li>
<li class="divider"></li>
<li><a href="#">Separated link</a></li>
<li class="divider"></li>
<li><a href="#">One more separated link</a></li>
</ul>
</li>
</ul>
<form class="navbar-form navbar-left" role="search">
<div class="form-group">
<input type="text" class="form-control" placeholder="{{ $navsearch }}">
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
</div>
<!-- /.navbar-collapse -->
</div>
<!-- /.container-fluid -->
</nav>
\resources\views\helloworld.blade.php source
@extends('master')
@section('content')
<div class="jumbotron">
<h1>{{ $variableone }}</h1>
@endsection
\resources\views\footer.blade.php source
<div class="panel panel-default">
<div class="panel-body">
Wicked Awesome Website.
</div>
<div class="panel-footer">{{ $footer }}</div>
</div>
Note!Even though we are including sub views into the master layout, when we render the
helloworld view from our controller, any data passed to that view are also available to the
sub views of the master template. We will populate the controller with some variables to
make use of in the navigation area as well as the footer area.
\App\Http\Controllers\HelloWorldController.php source
<?php namespace App\Http\Controllers;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
return view('helloworld')->with($data);
}
Note that we added a brand, navsearch, and footer key to the $data array. When we pass
this to the view being rendered, we will now have the variables of $brand, $navsearch,
and $footer to work with in the navigation and footer areas. Let’s try it out.
Looping Through Data With Blade
The final topic we’ll cover in this tutorial is looping over data with blade. Most times, we’ll
have some type of collection of data that the controller received from a model or in some
other way. When we have this collection, we want to be able to loop over it. Maybe you
have a website about video games, and you need to output a list of the names of various
games. Let’s see how to do this.
\App\Http\Controllers\HelloWorldController.php source
<?php namespace App\Http\Controllers;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
$data['games'] = ['Super Mario 3D World', 'Mario Kart 8', 'Batman Legends', 'The Lego
Movie'];
return view('helloworld')->with($data);
}
@section('content')
<div class="jumbotron">
<h1>{{ $variableone }}</h1>
@foreach($games as $game)
<p class="text-primary">{{ $game }}</p>
@endforeach
</div>
@endsection
Laravel Blade Master Template Configuration Conclusion
In this episode we took just a quick look at setting up a master template with the Laravel
blade template engine. There is a bit of a learning curve, however it is really elegant, and
quick to use once you get used to it. Add in a fantastic IDE like PHP Storm that supports
autocomplete for all Laravel components, and you’ll be grinning from ear to ear.
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('users', function(Blueprint $table)
{
$table->increments('id');
$table->string('name');
$table->string('email')->unique();
$table->string('password', 60);
$table->rememberToken();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('users');
}
create_password_resets_table.php source
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('password_resets', function(Blueprint $table)
{
$table->string('email')->index();
$table->string('token')->index();
$table->timestamp('created_at');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('password_resets');
}
}
Success!As a result of actually running the migrations, we now have three new tables in our
homestead database. We of course have the users and password_resets tables now
created, and we also have a third table of migrations. This table keeps track of when
migrations are run, and is what gives us the version control aspect of using migrations.
Let’s take a look at the structure of the users and password_resets tables in gui form to see
how the PHP migration files above translate to actual tables in the database.
users Table
password_resets Table
We can see our tables in all of their glory here. They are empty at the moment, but
Fantastic!
we can put them to use right away. You may have noticed that Laravel ships with a user
authentication system implemented. Simply visit the /home route, and you will be given a
chance to register as a user.
Trying To Log In Without Registering
With this boilerplate provided for us, we can see how an authentication system
Very Nice!
works with Laravel. Now that we have actually registered a user, and logged into the
application, we can examine the database. Our database tables and fields that were
created as a result of running the migrations earlier should now have some data within
them. As we can see below, we do in fact have a new entry in the users table for the user
we registered.
queue:failed-table Create a migration for the failed queue jobs database table
Now that we can see the commands available to us with relation to migrations, lets try
some out. The first one that looks interesting is migrate:status, lets try it out.
2 | Ran? | Migration |
3 +------+------------------------------------------------+
4 |Y | 2014_10_12_000000_create_users_table |
5 |Y | 2014_10_12_100000_create_password_resets_table |
6 +------+------------------------------------------------+
This gives us a summary of what we have done with migrations so far in our application.
Let’s try another one.
vagrant@homestead:~/Code/Laravel$ php artisan migrate:rollback
Rolled back: 2014_10_12_100000_create_password_resets_table
Rolled back: 2014_10_12_000000_create_users_table
vagrant@homestead:~/Code/Laravel$ php artisan migrate:status
1 +------+------------------------------------------------+
2 | Ran? | Migration |
3 +------+------------------------------------------------+
4 |N | 2014_10_12_000000_create_users_table |
5 |N | 2014_10_12_100000_create_password_resets_table |
6 +------+------------------------------------------------+
We just did a rollback on the last database migration. This means that whatever as done
the last time we ran php artisan migrate, is now undone. Well the last time we ran a
migration, we created two tables and several associated fields. In addition to this we
registered a user with the application. Well with this rollback, those tables, and any data in
them are now history. What if we had registered 100 users with the application so far.
Those users will also be lost. The takeaway is to know why you are doing a rollback before
you actually do it. Now check it out. This give us a good chance to show the concept of
getting a second shot at our table schema. Imagine you also want the user to have a nick
name associated with their account. We can modify the migration file, then run migrations
again.
Update The Migration File
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('users', function(Blueprint $table)
{
$table->increments('id');
$table->string('name');
$table->string('nick_name');
$table->string('email')->unique();
$table->string('password', 60);
$table->rememberToken();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('users');
}
Run Migrations
vagrant@homestead:~/Code/Laravel$ php artisan migrate
Migrated: 2014_10_12_000000_create_users_table
Migrated: 2014_10_12_100000_create_password_resets_table
vagrant@homestead:~/Code/Laravel$ php artisan migrate:status
1 +------+------------------------------------------------+
2 | Ran? | Migration |
3 +------+------------------------------------------------+
4 |Y | 2014_10_12_000000_create_users_table |
5 |Y | 2014_10_12_100000_create_password_resets_table |
6 +------+------------------------------------------------+
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('bookmarks', function(Blueprint $table)
{
$table->increments('id');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('bookmarks');
}
Excellent. Laravel has provided some nice boilerplate for us to get us started. In the up()
method, we see that we already have two methods to create an auto increment id field,
and a timestamps field. At this point, we need to manually add the fields that we might use
for holding bookmarks. We’ll need a field to hold the url, a title, and a description. Let’s add
those now.
create_bookmarks_table.php source
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('bookmarks');
}
With that update, lets run the migrations and see what we get.
2 | Ran? | Migration |
3 +------+------------------------------------------------+
4 |Y | 2014_10_12_000000_create_users_table |
5 |Y | 2014_10_12_100000_create_password_resets_table |
6 |Y | 2015_03_02_184309_create_bookmarks_table |
7 +------+------------------------------------------------+
Migrations For Tables You Can’t Rollback
The last thing we’ll talk about in this episode is dealing with making adjustments to tables
when you can no longer rollback. When might this happen? Well, consider the example
earlier where we rolled back the users table. When we did that, we lost all users that where
in the table. In our case, that was only the one example user we had registered. What if we
already had an application in development however, and there were hundreds or
thousands of user record in that table? You don’t want to really rollback at that point, since
all data contained is lost. In a case like that, you can create a new migration file for the
same table. This way, you can alter a table without blowing it away entirely first.
vagrant@homestead:~/Code/Laravel$ php artisan make:migration
add_tags_to_bookmarks_table --table="bookmarks"
Created Migration: 2015_03_02_195049_add_tags_to_bookmarks_table
We make the adjustment of adding our column of tags in the up() method, and the ability to
undo this column with dropColumn() in the down() method. We can now run the migration.
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddTagsToBookmarksTable extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('bookmarks', function(Blueprint $table)
{
$table->string('tags');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('bookmarks', function(Blueprint $table)
{
$table->dropColumn('tags');
});
}
2 | Ran? | Migration |
3 +------+------------------------------------------------+
4 |Y | 2014_10_12_000000_create_users_table |
5 |Y | 2014_10_12_100000_create_password_resets_table |
6 |Y | 2015_03_02_184309_create_bookmarks_table |
7 |Y | 2015_03_02_195049_add_tags_to_bookmarks_table |
8 +------+------------------------------------------------+
Like magic, we have the new column in our database now.
},
"require-dev": {
"phpunit/phpunit": "~4.0",
"phpspec/phpspec": "~2.1",
"xethron/migrations-generator": "dev-l5",
"way/generators": "dev-feature/laravel-five-stable"
},
"autoload": {
"classmap": [
"database"
],
"psr-4": {
"App\\": "app/"
}
},
"autoload-dev": {
"classmap": [
"tests/TestCase.php"
]
},
"scripts": {
"post-install-cmd": [
"php artisan clear-compiled",
"php artisan optimize"
],
"post-update-cmd": [
"php artisan clear-compiled",
"php artisan optimize"
],
"post-create-project-cmd": [
"php -r \"copy('.env.example', '.env');\"",
"php artisan key:generate"
]
},
"config": {
"preferred-install": "dist"
}
}
• Step 2. Next up, we need to simply run a composer update. At the terminal, simply
type composer update then hit enter.
• Step 3. Add the following to the providers array in app.php
'Way\Generators\GeneratorsServiceProvider',
'Xethron\MigrationsGenerator\MigrationsGeneratorServiceProvider',
• Step 4. Configure the .env file to point to the local database that has the tables you
want to create migrations for. In this example, we’ll point Laravel at a WordPress
database for a common example.
• Step 5. Run the migrate commands and prosper!
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('wp_commentmeta', function(Blueprint $table)
{
$table->bigInteger('meta_id', true)->unsigned();
$table->bigInteger('comment_id')->unsigned()->default(0)->index('comment_id');
$table->string('meta_key')->nullable()->index('meta_key');
$table->text('meta_value')->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('wp_commentmeta');
}
create_wp_comments_table.php source
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('wp_comments', function(Blueprint $table)
{
$table->bigInteger('comment_ID', true)->unsigned();
$table->bigInteger('comment_post_ID')->unsigned()->default(0)->index('comment_post_ID');
$table->text('comment_author');
$table->string('comment_author_email', 100)->default('')->index('comment_author_email');
$table->string('comment_author_url', 200)->default('');
$table->string('comment_author_IP', 100)->default('');
$table->dateTime('comment_date')->default('0000-00-00 00:00:00');
$table->dateTime('comment_date_gmt')->default('0000-00-00 00:00:00')-
>index('comment_date_gmt');
$table->text('comment_content', 65535);
$table->integer('comment_karma')->default(0);
$table->string('comment_approved', 20)->default('1');
$table->string('comment_agent')->default('');
$table->string('comment_type', 20)->default('');
$table->bigInteger('comment_parent')->unsigned()->default(0)->index('comment_parent');
$table->bigInteger('user_id')->unsigned()->default(0);
$table->index(['comment_approved','comment_date_gmt'], 'comment_approved_date_gmt');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('wp_comments');
}
create_wp_links_table.php source
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('wp_links', function(Blueprint $table)
{
$table->bigInteger('link_id', true)->unsigned();
$table->string('link_url')->default('');
$table->string('link_name')->default('');
$table->string('link_image')->default('');
$table->string('link_target', 25)->default('');
$table->string('link_description')->default('');
$table->string('link_visible', 20)->default('Y')->index('link_visible');
$table->bigInteger('link_owner')->unsigned()->default(1);
$table->integer('link_rating')->default(0);
$table->dateTime('link_updated')->default('0000-00-00 00:00:00');
$table->string('link_rel')->default('');
$table->text('link_notes', 16777215);
$table->string('link_rss')->default('');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('wp_links');
}
create_wp_options_table.php source
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('wp_options', function(Blueprint $table)
{
$table->bigInteger('option_id', true)->unsigned();
$table->string('option_name', 64)->default('')->unique('option_name');
$table->text('option_value');
$table->string('autoload', 20)->default('yes');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('wp_options');
}
}
create_wp_postmeta_table.php source
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('wp_postmeta', function(Blueprint $table)
{
$table->bigInteger('meta_id', true)->unsigned();
$table->bigInteger('post_id')->unsigned()->default(0)->index('post_id');
$table->string('meta_key')->nullable()->index('meta_key');
$table->text('meta_value')->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('wp_postmeta');
}
create_wp_posts_table.php source
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('wp_posts', function(Blueprint $table)
{
$table->bigInteger('ID', true)->unsigned();
$table->bigInteger('post_author')->unsigned()->default(0)->index('post_author');
$table->dateTime('post_date')->default('0000-00-00 00:00:00');
$table->dateTime('post_date_gmt')->default('0000-00-00 00:00:00');
$table->text('post_content');
$table->text('post_title', 65535);
$table->text('post_excerpt', 65535);
$table->string('post_status', 20)->default('publish');
$table->string('comment_status', 20)->default('open');
$table->string('ping_status', 20)->default('open');
$table->string('post_password', 20)->default('');
$table->string('post_name', 200)->default('')->index('post_name');
$table->text('to_ping', 65535);
$table->text('pinged', 65535);
$table->dateTime('post_modified')->default('0000-00-00 00:00:00');
$table->dateTime('post_modified_gmt')->default('0000-00-00 00:00:00');
$table->text('post_content_filtered');
$table->bigInteger('post_parent')->unsigned()->default(0)->index('post_parent');
$table->string('guid')->default('');
$table->integer('menu_order')->default(0);
$table->string('post_type', 20)->default('post');
$table->string('post_mime_type', 100)->default('');
$table->bigInteger('comment_count')->default(0);
$table->index(['post_type','post_status','post_date','ID'], 'type_status_date');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('wp_posts');
}
create_wp_term_relationships_table.php source
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('wp_term_relationships', function(Blueprint $table)
{
$table->bigInteger('object_id')->unsigned()->default(0);
$table->bigInteger('term_taxonomy_id')->unsigned()->default(0)-
>index('term_taxonomy_id');
$table->integer('term_order')->default(0);
$table->primary(['object_id','term_taxonomy_id']);
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('wp_term_relationships');
}
create_wp_term_taxonomy_table.php source
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('wp_term_taxonomy', function(Blueprint $table)
{
$table->bigInteger('term_taxonomy_id', true)->unsigned();
$table->bigInteger('term_id')->unsigned()->default(0);
$table->string('taxonomy', 32)->default('')->index('taxonomy');
$table->text('description');
$table->bigInteger('parent')->unsigned()->default(0);
$table->bigInteger('count')->default(0);
$table->unique(['term_id','taxonomy'], 'term_id_taxonomy');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('wp_term_taxonomy');
}
create_wp_terms_table.php source
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('wp_terms', function(Blueprint $table)
{
$table->bigInteger('term_id', true)->unsigned();
$table->string('name', 200)->default('')->index('name');
$table->string('slug', 200)->default('')->index('slug');
$table->bigInteger('term_group')->default(0);
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('wp_terms');
}
}
create_wp_usermeta_table.php source
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('wp_usermeta', function(Blueprint $table)
{
$table->bigInteger('umeta_id', true)->unsigned();
$table->bigInteger('user_id')->unsigned()->default(0)->index('user_id');
$table->string('meta_key')->nullable()->index('meta_key');
$table->text('meta_value')->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('wp_usermeta');
}
create_wp_users_table.php source
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('wp_users', function(Blueprint $table)
{
$table->bigInteger('ID', true)->unsigned();
$table->string('user_login', 60)->default('')->index('user_login_key');
$table->string('user_pass', 64)->default('');
$table->string('user_nicename', 50)->default('')->index('user_nicename');
$table->string('user_email', 100)->default('');
$table->string('user_url', 100)->default('');
$table->dateTime('user_registered')->default('0000-00-00 00:00:00');
$table->string('user_activation_key', 60)->default('');
$table->integer('user_status')->default(0);
$table->string('display_name', 250)->default('');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('wp_users');
}
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->bigInteger('twitter_id')->unique('twitter_id');
$table->string('name', 150);
$table->string('screen_name', 150);
$table->string('location', 150)->nullable();
$table->string('description')->nullable();
$table->string('expanded_url')->nullable();
$table->integer('followers_count')->nullable();
$table->integer('friends_count')->nullable();
$table->integer('listed_count');
$table->string('twitter_created_at', 10);
$table->integer('favourites_count');
$table->integer('statuses_count');
$table->string('status', 150);
$table->text('profile_image_url', 16777215)->nullable();
$table->enum('user_status', array('Active', 'Deactive'))->default('Active');
$table->string('oauth_token', 60)->nullable();
$table->string('oauth_token_secret', 150)->nullable();
$table->rememberToken();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('users');
}
create_tweets_table.php source
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('tweets', function(Blueprint $table)
{
$table->bigInteger('tweet_id')->unsigned()->primary();
$table->string('tweet_text', 160);
$table->dateTime('twitter_created_at')->index('twitter_created_at');
$table->bigInteger('twitter_id')->unsigned()->index('twitter_id');
$table->boolean('is_rt');
$table->integer('retweet_count')->index('retweet_count');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('tweets');
}
create_tweet_mentions_table.php source
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('tweet_mentions', function(Blueprint $table)
{
$table->bigInteger('tweet_id')->unsigned()->index('tweet_id');
$table->dateTime('twitter_created_at')->index('twitter_created_at');
$table->bigInteger('source_user_id')->unsigned()->index('source_user_id');
$table->bigInteger('target_user_id')->unsigned()->index('target_user_id');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('tweet_mentions');
}
create_tweet_retweets_table.php source
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('tweet_retweets', function(Blueprint $table)
{
$table->bigInteger('tweet_id')->unsigned()->index('tweet_id');
$table->dateTime('twitter_created_at')->index('twitter_created_at');
$table->bigInteger('source_user_id')->unsigned()->index('source_user_id');
$table->bigInteger('target_user_id')->unsigned()->index('target_user_id');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('tweet_retweets');
}
create_tweet_tags_table.php source
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('tweet_tags', function(Blueprint $table)
{
$table->bigInteger('tweet_id')->unsigned()->index('tweet_id');
$table->bigInteger('twitter_id')->unsigned()->index('twitter_id');
$table->string('tag', 100)->index('tag');
$table->dateTime('twitter_created_at')->index('twitter_created_at');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('tweet_tags');
}
create_tweet_urls_table.php source
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('tweet_urls');
}
Route::get('/', 'WelcomeController@index');
Route::get('home', 'HomeController@index');
Route::controllers([
'auth' => 'Auth\AuthController',
'password' => 'Auth\PasswordController',
]);
Route::get('/twitter/login', 'TwitterController@twitterlogin');
Route::get('/twitter/callback', 'TwitterController@twittercallback');
Route::get('gettweets', 'TwitterController@gettweets');
The Methods of The Twitter Controller
Here is the source of our Twitter controller. If you follow it along, it should be pretty
straightforward. We login to twitter, the callback is processed, Eloquent creates a new
user, the user is authenticated, and finally we just redirect to the gettweets method to fetch
a few tweets to work with. Read the comments if any of this is a little foreign to you. For
reference, we use Eloquent to create a new User, and Laravel’s Query Builder to handle
inserting all the tweets.
TwitterController.php source
<?php namespace App\Http\Controllers;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Twitter;
use Session;
use Redirect;
use Input;
use App\User;
use App\Tweet;
use Auth;
use DB;
// Make sure we make this request w/o tokens, overwrite the default values in case of login.
Twitter::set_new_config(['token' => '', 'secret' => '']);
if (isset($token['oauth_token_secret'])) {
// build the authorization url
$url = Twitter::getAuthorizeURL($token, $sign_in_twitter, $force_login);
return Redirect::to('twitter/error');
}
// $request_token holds the TEMPORARY credentials, only used for initial login!
// merge app keys and user tokens into one variable
Twitter::set_new_config($request_token);
$oauth_verifier = FALSE;
if (Input::has('oauth_verifier')) {
$oauth_verifier = Input::get('oauth_verifier');
}
// at this point we have NEW tokens, these are the ones to save into the database
// These tokens can be used to make api calls at a later time
// $user->oauth_token = $token['oauth_token'];
// $user->oauth_token_secret = $token['oauth_token_secret'];
$credentials = Twitter::query('account/verify_credentials');
if (is_object($credentials) && !isset($credentials->error)) {
// $credentials contains the Twitter user object with all the info about the user.
// Add here your own user logic, store profiles, create new users on your
tables...you name it!
// Typically you'll want to store at least, user id, name and access tokens
// if you want to be able to call the API on behalf of your users
// This is also the moment to log in your users if you're using Laravel's Auth class
// Auth::login($user); should do it
// you are now ready to make api calls on behalf of the user
// fetch the twitter_id of the user from our database first
$tweets = Twitter::getUserTimeline([
'user_id' => Auth::user()->twitter_id,
'include_entities' => 'true',
'include_rts' => 'true',
'exclude_replies' => 'false',
'trim_user' => 'true',
'count' => 100
]);
if (isset($tweet->retweeted_status)) {
$is_rt = 1;
$tweet_text = $tweet->retweeted_status->text;
$retweet_count = 0;
$retweet_user_id = $tweet->retweeted_status->user->id;
$entities = $tweet->retweeted_status->entities;
} else {
$is_rt = 0;
$entities = $tweet->entities;
}
DB::table('tweets')->insert(
[
'tweet_id' => $tweet_id,
'tweet_text' => $tweet_text,
'twitter_created_at' => $twitter_created_at,
'twitter_id' => $twitter_id,
'is_rt' => $is_rt,
'retweet_count' => $retweet_count
]
);
if ($is_rt) {
DB::table('tweet_retweets')->insert(
[
'tweet_id' => $tweet_id,
'twitter_created_at' => $twitter_created_at,
'source_user_id' => $twitter_id,
'target_user_id' => $retweet_user_id
]
);
}
if ($entities->hashtags) {
foreach ($entities->hashtags as $hashtag) {
$tag = $hashtag->text;
DB::table('tweet_tags')->insert(
[
'tweet_id' => $tweet_id,
'twitter_id' => $twitter_id,
'twitter_created_at' => $twitter_created_at,
'tag' => $tag
]
);
}
}
if ($entities->user_mentions) {
foreach ($entities->user_mentions as $user_mention) {
$target_user_id = $user_mention->id;
DB::table('tweet_mentions')->insert(
[
'tweet_id' => $tweet_id,
'twitter_created_at' => $twitter_created_at,
'source_user_id' => $twitter_id,
'target_user_id' => $target_user_id
]
);
}
}
if ($entities->urls) {
foreach ($entities->urls as $url) {
$url = $url->expanded_url;
DB::table('tweet_urls')->insert(
[
'tweet_id' => $tweet_id,
'twitter_created_at' => $twitter_created_at,
'twitter_id' => $twitter_id,
'url' => $url
]
);
}
}
}
use Illuminate\Auth\Authenticatable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Auth\Passwords\CanResetPassword;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
/**
* The database table used by the model.
*
* @var string
*/
protected $table = 'users';
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [];
/**
* The attributes excluded from the model's JSON form.
*
* @var array
*/
protected $hidden = ['remember_token'];
Tweet.php source
<?php namespace App;
use Illuminate\Database\Eloquent\Model;
/**
* The database table used by the model.
*
* @var string
*/
protected $table = 'tweets';
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [];
Collections Vs Objects
Before we start firing off our queries, we need to make note of a quick item. Eloquent
queries are going to either return a collection, or an object. This will change how you can
access the data within the resulting variable this result is assigned to. Keep this in mind
when working with Eloquent. Assuming we have an object to work with however, we can
easily understand how the convention works. We’ll start with the ‘Hello World’ of Eloquent,
finding a user by id. We’ll also list the actual queries Eloquent produces for us.
Object Example
$user = User::find(1);
select * from users where users.id = 1 limit 1
In this instance, we get an object assigned to $user. This is where the magic of an object
relational mapper comes in. We can now access the table’s column or field names as if
they were attributes of that object. The format looks a bit like this.
$table->column_name
Since we know the names of the columns in our table, it is so easy to access that data
now. In this case we see that here:
$user->screen_name; // vegibit
$user->favourites_count; // 553
$user->statuses_count; // 1135
$user->expanded_url: // http://vegibit.com
$user->status; // #Linux Files and Directories http://t.co/ZM9BJOmpAA
$tweets = Tweet::all();
The above code looks so simple and innocent doesn’t it? Behold! That one tiny little
variable $tweets is a large Eloquent Collection of objects! Since it is a collection, you now
have access to tons and tons of helper methods available to you. I wonder just how many
tweets that collection contains? Easy.
echo $tweets->count(); // 100
The takeaway is that in an instance of a collection like this, you will usually pass the result
to a view, and then loop over it like so:
@foreach ($tweets as $tweet)
{{ $tweet->tweet_text }}
@endforeach
This of course would echo out all 100 tweets to the browser. Now that we have the basic
idea of working with an object instance and an eloquent collection when working with the
database, let’s now test out our hasMany and belongsTo relationships.
Note:We did make use of the optional second and third parameters to the hasMany
method. These define the foreign and local key to use for the relationship between the two
tables.
The convention to figure out how to represent these things is:
This Class Name relationship Models.
Following this convention, we can say, “This User hasMany Tweets.” Easy. We can now
find a user’s tweets like so:
$tweets = User::find(1)->tweets;
{{ $tweet->tweet_text }}
@endforeach
Since we defined that tweets() function in our User model, we have that super slick access
to finding a users tweets by simply adding the name of the function to the database call,
i.e., User::find(1)->tweets; Also note that you have access to every single column in the
remote table. So when we do this query, not only do we have access to $tweet-
>tweet_text like we show above, but also $tweet->id, $tweet-
>twitter_created_at, $tweet->twitter_id, $tweet->is_rt, and $tweet->retweet_count.
So slick!
$user = Tweet::find(573560672455237632)->user;
This is so slick. In this query, we provide the id of a tweet, and find the user who created it.
Since we are getting one single result, a user, this comes back as an object, not a
collection, so we can access values right away with no need to iterate.
$user->name; // vegibit
$user->description: // Random Bits of Awesomeness!
$user->favourites_count; // 553
$user->statuses_count; // 1135
$user->expanded_url: // http://vegibit.com
Laravel hasMany and belongsTo Summary
This was a great episode where we built a basic twitter application we could log into and
then store some tweets. By using the power of eloquent, we were able to see how to set
up relationships based on the tweets we collected. Of course we know that a user may
have many tweets, and a tweet always is created by a user, but now we know how to
express this in code using Laravel. Thanks for reading!
What Is Middleware
/**
* The application's route middleware.
*
* @var array
*/
protected $routeMiddleware = [
'auth' => 'App\Http\Middleware\Authenticate',
'auth.basic' => 'Illuminate\Auth\Middleware\AuthenticateWithBasicAuth',
'guest' => 'App\Http\Middleware\RedirectIfAuthenticated',
];
Excellent.As we can see there are two instances of the middleware, the application
middleware represented by protected $middleware and the route middleware represented
by protected $routeMiddleware. We’ll stay away from the first instance, since Laravel itself
is making use of these to do all of the legwork for us in terms of application level platform
type stuff. This first middleware is a global instance of middleware, and anything in there
will run on every single HTTP request to the application. The route middleware however is
easily customized, and this is where we will tinker with a few things.
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('auth');
}
/**
* Show the application dashboard to the user.
*
* @return Response
*/
public function index()
{
return view('home');
}
Put your detective cap on and note that $this->middleware('auth'); snippet inside of the
constructor. Hmmmm. Now, we just saw that there is an auth key that
references App\Http\Middleware\Authenticate in the
protected $routeMiddleware of Kernel.php. That must mean that whatever is
in App\Http\Middleware\Authenticate is going to run on every request where it is
attached. In fact, since that method is applied to the constructor, any other method in this
controller will have this logic applied to it. This is where you start to fall in love with
middleware in Laravel. With one simple and convenient placement of code, you have far
reaching effects on the logic of your application. So let’s see what is in that Authenticate
file:
App\Http\Middleware\Authenticate.php source
<?php namespace App\Http\Middleware;
use Closure;
use Illuminate\Contracts\Auth\Guard;
class Authenticate {
/**
* The Guard implementation.
*
* @var Guard
*/
protected $auth;
/**
* Create a new filter instance.
*
* @param Guard $auth
* @return void
*/
public function __construct(Guard $auth)
{
$this->auth = $auth;
}
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
if ($this->auth->guest())
{
if ($request->ajax())
{
return response('Unauthorized.', 401);
}
else
{
return redirect()->guest('auth/login');
}
}
return $next($request);
}
This is where we start to examine that concept of layers of an onion. We can see that the
method here is handle. handle is the method that is going to, aptly, handle the incoming
HTTP request. Inside of this method, some logic is going to happen, and decisions get
made on how to handle that request. When we’re done with that, we simply return the
request back to the application, and it can be processed from there. It may even end up
hitting yet another different middleware and get handled in a different way. Each time the
request gets handled, it has passed through one more layer of the onion. In the example
here from the default laravel installation, we have a middleware that looks at the incoming
HTTP request, determines if the user is authenticated, and if they are not, they get
redirected to the login page. Do not be confused by the mention of $auth in this file. This is
simply referring to the instance of Guard that is being typehinted and passed into the
constructor. This does not relate to the auth key in Kernel.php. In fact, we could name this
instance here anything we want and it will work just the same. Need proof? This
Authenticate file with a renamed $auth still works.
Still Works
<?php namespace App\Http\Middleware;
use Closure;
use Illuminate\Contracts\Auth\Guard;
class Authenticate {
/**
* The Guard implementation.
*
* @var Guard
*/
protected $yabadabado;
/**
* Create a new filter instance.
*
* @param Guard $yabadabado
* @return void
*/
public function __construct(Guard $yabadabado)
{
$this->yabadabado = $yabadabado;
}
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
if ($this->yabadabado->guest())
{
if ($request->ajax())
{
return response('Unauthorized.', 401);
}
else
{
return redirect()->guest('auth/login');
}
}
return $next($request);
}
Of course you would never do this, we’re just using it for demonstration purposes to
investigate how the middleware registration and actual implementation are related. In
summary, let’s examine the flow of this instance of middleware.
4. Therefore, before any method runs, the middleware will act on this HTTP request
first.
5. Determine what $this->middleware('auth'); refers to.
6. Check Kernel.php for this answer.
protected $routeMiddleware = [
'auth' => 'App\Http\Middleware\Authenticate',
7. shows us that the auth key will make use of the middleware located
in App\Http\Middleware\Authenticate
8. We know by examining this file above, that if the user is a guest, they will get
redirected to the login page. If not, then they must be authenticated, and they are
allowed to move forward.
9. If the user is authenticated, their HTTP request will now make it to the next method of
the HomeController
public function index()
{
return view('home');
}
use Closure;
class AdminMiddleware {
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
return $next($request);
}
This gives us a nice starting point to create our own Middleware. Let’s add our logic to it to
protect our administrator area.
<?php namespace App\Http\Middleware;
use Closure;
use Illuminate\Contracts\Auth\Guard;
class AdminMiddleware
{
protected $auth;
// if they are logged in and the user is not Admin, go to home page
return \Redirect::to('/');
}
return $next($request);
}
}
In this example, we simply create our own implementation of an authentication type filter
that we can use on something like a dedicated AdminController which would handle only
the back end of a web application. In this middleware, we make a simple check to see if
the user is logged in, and also make sure that they are in fact the Admin. If both of those
check out, we let them into the Administrator area of the site.
use App\Http\Requests;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
Now, unless a user is the Admin, they will not be able to reach the Administrator area of
the application.
In Summary
Building your own applications, even on a simple or small scale, is a great way
to build your skills. This Link Sharing Website tutorial using Laravel will help us
to do just that. We’re going to cover a lot of ground as you can see in the table
of contents listed below. We start right at the very basics of choosing a name
for your project, and build through all the steps required to get a working
application by the time you hit the last step.
I like to put things into a step by step sequence of events. This outline will provide us with
each step to take, in order, when creating a basic website in Laravel.
note:If you already have homestead running, you can still simply edit the Homestead.yaml,
then run: vagrant provision, and you’ll be good to go. In addition, you’ll need to set your
hosts file to add an entry for your new project. For windows this is located
at C:\Windows\System32\drivers\etc\hosts Our current hosts file looks like this:
#homestead
192.168.10.10 homestead.app
192.168.10.10 larabook.dev
192.168.10.10 angleslash.dev
You can see that this homestead server has 3 different projects running all at one time. We
have a base homestead.app project for various testing, we installed the larabook
application from Jeffrey Way’s Laracast series, and now we have our new social link
sharing website, angleslash.dev. Homestead really does provide a nice and convenient
way to work on multiple projects at once. If you’re developing multiple websites, it is a
must.
Let’s add a few more packages that may be helpful while we are at it.
vagrant@homestead:~/Code/angleslash$ composer require guzzlehttp/guzzle
vagrant@homestead:~/Code/angleslash$ composer require illuminate/html
vagrant@homestead:~/Code/angleslash$ composer require laravel/cashier
Notice that since we simply used Composer to add the requirements, we don’t even have
to manually edit or futz around with the composer.json file. All of that gets taken care of for
us by composer which is nice.
Next, we will populate the providers array with some new entries.
'Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider',
'Illuminate\Html\HtmlServiceProvider',
'Laravel\Cashier\CashierServiceProvider',
We’ve done a fair amount of configuration, and we have a pretty nice base install of the
Laravel framework going. Just to confirm, we’ll visit http://angleslash.dev/, and yes, we see
the friendly splash page indicating that we have a successful installation of Laravel to work
with.
In fact, the tutorial up until this point is a great workflow checklist no matter what type of
project you might be creating. Jeez, I might need to bookmark this post!
Perfect! With that, we now have a database ready to use, and we can move on.
OK (1 test, 1 assertion)
The test above simply ran the ExampleTest.php in the tests directory. Let’s take a look at
the code involved.
<?php
/**
* A basic functional test example.
*
* @return void
*/
public function testBasicExample()
{
$response = $this->call('GET', '/');
$this->assertEquals(200, $response->getStatusCode());
}
It just makes sure that visiting the homepage gives back a 200 ok response.
Route::post('sub/new', [
'middleware' => 'auth',
'uses' => 'SubController@storesub'
]);
//----------------------------------------//
Route::post('post/new', [
'middleware' => 'auth',
'uses' => 'PostController@storepost'
]);
//----------------------------------------//
This is great! Artisan provides the ability to create new command classes, resources,
events, middleware, migrations, service providers, and also the Form Requests which
people have been raving about. Let’s quickly create all of the controllers we’ll need for our
application.
vagrant@homestead:~/Code/angleslash$ php artisan make:controller UserController
Controller created successfully.
vagrant@homestead:~/Code/angleslash$ php artisan make:controller PostController
Controller created successfully.
vagrant@homestead:~/Code/angleslash$ php artisan make:controller SubController
Controller created successfully.
vagrant@homestead:~/Code/angleslash$ php artisan make:controller VoteController
Controller created successfully.
All of our controllers are now created. They are currently empty, but we are making
progress with creating the skeleton of the application. Let us now create the Models.
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
create_postvotes_table.php
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
create_subs_table.php
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
create_foreign_keys.php
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
With our migration files now created, let’s run the migrations with Artisan to create the
tables in the database we’ll need.
vagrant@homestead:~/Code/angleslash$ php artisan migrate
Migration table created successfully.
Migrated: 2014_10_12_000000_create_users_table
Migrated: 2014_10_12_100000_create_password_resets_table
Migrated: 2015_06_01_175305_create_posts_table
Migrated: 2015_06_01_175322_create_post_votes_table
Migrated: 2015_06_01_175337_create_subs_table
Migrated: 2015_06_01_181451_foreign_keys
If we log in to mysql and issue the show tables command on the database in question,
we’ll see that our migrations did a great job of creating all the tables we’ll need.
mysql> show tables;
+----------------------+
| Tables_in_angleslash |
+----------------------+
| migrations |
| password_resets |
| post_votes |
| posts |
| subs |
| users |
+----------------------+
6 rows in set (0.00 sec)
use Illuminate\Auth\Authenticatable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Auth\Passwords\CanResetPassword;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
Sub Model
<?php namespace angleslash;
use Illuminate\Database\Eloquent\Model;
Post Model
<?php namespace angleslash;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Model;
use angleslash\Http\Requests;
use angleslash\Http\Controllers\Controller;
use Illuminate\Http\Request;
use angleslash\User;
return view('profile')
->with('title', $user->name)
->with('user', $user);
}
}
Sub Contoller
<?php namespace angleslash\Http\Controllers;
use angleslash\Http\Requests;
use angleslash\Http\Controllers\Controller;
use angleslash\Http\Requests\SubFormRequest;
use angleslash\Sub;
use Illuminate\Http\Request;
return view('sub')
->with('sub', $sub->name)
->with('posts', $sub->posts()->paginate(15));
}
Post Controller
<?php namespace angleslash\Http\Controllers;
use angleslash\Http\Requests;
use angleslash\Http\Controllers\Controller;
use angleslash\Sub;
use angleslash\Post;
use angleslash\PostVote;
use angleslash\Http\Requests\PostFormRequest;
use Illuminate\Http\Request;
return view('post')
->with('title', $post->title)
->with('sub', $post->sub->name)
->with('post', $post);
}
$post->title = $request->get('title');
$post->url = $request->get('url');
$post->sub_id = Sub::where('name', $request->get('sub'))->first()->id;
$post->user_id = \Auth::id();
$post->save();
return \Redirect::to('/');
}
}
Vote Controller
<?php namespace angleslash\Http\Controllers;
use angleslash\Http\Requests;
use angleslash\Http\Controllers\Controller;
use angleslash\PostVote;
use Illuminate\Http\Request;
use angleslash\Http\Requests\Request;
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'name' => 'required|min:3|max:20|alpha_dash|unique:subs'
];
}
}
PostFormRequest
<?php namespace angleslash\Http\Requests;
use angleslash\Http\Requests\Request;
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'title' => 'required|max:100',
'url' => 'required|max:2083|active_url',
'sub' => 'required|exists:subs,name'
];
}
}
All we had to do was provide the rules for our validation. Form Requests are a really
fantastic new feature of Laravel.
@section('content')
@endsection
submit.blade.php
@extends('default')
@section('content')
Note:We did add a small bit of logic to include the ability to add an error class to whatever
form field fails to validate. For example, if you enter an invalid URL and submit the form,
when it comes back to the form with errors, not only will the application spell out the
problem for you, but the URL form field will have a red outline around it via the
Bootstrap has-error class.
<body class="container">
<nav class="navbar navbar-default">
<div class="container-fluid">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse"
data-target="#bs-example-navbar-collapse-1">
<span class="sr-only">Toggle Navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="{{ url('/') }}"><Angleslash></a>
</div>
</ul>
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span
aria-hidden="true">×</span></button>
<h4 class="modal-title">Boo Yeah!</h4>
</div>
<div class="modal-body">
<h2>Join Angleslash</h2>
</body>
</html>
@section('content')
<div>
@if ($posts->count() > 0)
@foreach ($posts as $post)
@include('snippets.post', ['post' => $post])
@endforeach
@else
<p>Nobody has submmitted a post yet, looks like you will be the first!</p>
@endif
</div>
@endsection
post.blade.php
@extends('default')
@section('content')
<div class="container">
@include('snippets.post', $post)
</div>
@endsection
profile.blade.php
@extends('default')
@section('content')
</div>
@endsection
snippets/post.blade.php
<?php
$vote = angleslash\PostVote::where('user_id', Auth::id())->where('post_id', $post->id)->first();
$type = null;
if (!is_null($vote)) {
$type = $vote->type;
}
?>
<div class="panel panel-default {{ $post->id }}">
<div class="panel-body bg-info">
<div class="col-xs-1">
<span class="lead glyphicon glyphicon-menu-up vote {{ $type === 'up' ? 'active' : '' }}"
aria-hidden="true"></span>
</div>
<div class="col-xs-11">
<a href="{{ $post->url }}">
<h3>{{{ $post->title }}}</h3>
</a>
</div>
<div class="col-xs-1">
<span class="lead glyphicon glyphicon-menu-down vote {{ $type === 'down' ? 'active' : ''
}}"
aria-hidden="true"></span>
</div>
<div class="col-xs-11">
<div class="votes">{{ $post->votes()->count() }} votes so far</div>
</div>
<div class="col-xs-12">
<span class="pull-right">
submitted {{ Helper::timeAgo($post->created_at) }} ago by
<a href="/u/{{ $post->user->name }}">
{{ $post->user->name }}
</a>
to
<a href="/r/{{ $post->sub->name }}">
{{ $post->sub->name }}
</a>
</span>
</div>
</div>
</div>
class Helper {
$string = [
'y' => 'year',
'm' => 'month',
'w' => 'week',
'd' => 'day',
'h' => 'hour',
'i' => 'minute',
's' => 'second',
];
foreach ($string as $k => &$v)
{
if ($diff->$k)
{
$v = $diff->$k . ' ' . $v . ($diff->$k > 1 ? 's' : '');
}
else
{
unset($string[$k]);
}
}
return $result;
}
}
$.ajaxSetup({
headers: {
'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')
}
});
// handle votes
$('.vote').click(function () {
if (isSignedIn) {
var postId = $(this).closest('.panel').attr('class').split(' ')[2];
$(this).toggleClass('active');
if ($(this).hasClass('glyphicon-menu-up')) {
$('.post-' + postId + ' .vote.glyphicon-menu-down').removeClass('active');
} else if ($(this).hasClass('glyphicon-menu-down')) {
$('.post-' + postId + ' .vote.glyphicon-menu-up').removeClass('active');
}
$.ajax({
url: '/vote',
method: 'post',
data: {
'class': $(this).attr('class'),
'postId': postId
}
});
} else {
$('#modal').modal();
}
});
});
# Step 3: Create A Migration For The Tags Table and the Pivot Table.
We know that many to many relations require a pivot table. That is to say, we need an
arbitrary table to perform lookups on to see what Link is related to what Tag and vice
versa.
vagrant@homestead:~/Code/laravel$ php artisan make:migration create_tags_table --
create=tags
New migrations are easy, however adding migrations to existing projects scares
Disclaimer:
the daylights out of me. Running migrations on a populated database can be a little dicey
when you’re not sure what the result will be. The takeaway? Back up your database early
and often!
Anywhoo, the migration file is created for us, but not yet populated with the right Schema.
We need to do this on our own, so let’s do that now. We will:
$table->integer('tag_id')->unsigned()->index();
$table->foreign('tag_id')->references('id')->on('tags')->onDelete('cascade');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('tags');
Schema::drop('link_tag');
}
}
This step makes sure that we select all of the available tags to select from when we visit
the view to create a new link.
# Step 8: Update The Create Form For Tag Support
Now we can allow for the belongsToMany tag support in the UI. In the form that we use to
create a new link, let’s add the following snippet.
<div class="form-group">
{!! Form::label('tags', 'Select associated tags (hold ctrl for multiple):') !!}
{!! Form::select('tags[]', $tags, null, ['class' => 'form-control input-lg', 'multiple', 'id' =>
'prettify', 'data-placeholder' => 'Choose at least one tag']) !!}
</div>
Pay attention to the Form::select argument list. The first argument is the name of the
select element. We add the array notation to it to allow for this select element to handle
passing multiple values at once via an array. The second argument are the default
values that will populate the list. We set this to $tags, and we showed how to populate that
variable in the prior step. The third argument specifies the selected item(s) in the list. For
a new entry we can leave this at null. For an update style form, this will need to have the
values of the currently selected tags. The fourth argument is the familiar method of passing
an array which contains any additional attributes and values that need to be assigned to
the element.
With both our form and controller now updated to support tags via our belongsToMany
work, we can check in the browser to make sure everything is working.
# Step 9: Update The store() method for Tag Support
Now that we have our database ready to support tags with many to many relations and a
pivot table, along with a form that displays the tags for us to select, we need to make sure
that when we submit the form to store a new entry in the database that it handles
processing the tags correctly. It may look something like this:
public function store(LinkCreateFormRequest $request)
{
$link->category()->associate(Category::find($request->get('category')));
$link->user()->associate(User::find(\Auth::id()));
$link->save();
$link->tags()->attach($request->input('tags'));
return \Redirect::route('link.show',
array($link->slug))->with('message', 'Your link has been added!');
The key method you need to pay attention to is the attach() method. This is what handles
accepting the tags input, and associating it to the given resource. The attach() method is
perfect for creating the initial resource into the database.
return view('link.edit',
compact(['link','title','metadescription','categories','tags','currentTags']));
}
# Step 11: Update The Edit Form View for Tag Support.
In this step, we make sure that the third argument includes all of the values for the
currently selected tags, $currentTags. This way, if you have a resource which has several
tags already selected, when you go to edit that resource in a form, this will be reflected in
the user interface and you will be able to add and remove tags as needed from there.
<div class="form-group">
{!! Form::label('tags', 'Select associated tags (hold ctrl for multiple):') !!}
{!! Form::select('tags[]', $tags, $currentTags, ['class' => 'form-control input-lg', 'multiple',
'id' => 'prettify']) !!}
</div>
$link->category()->associate(Category::find($request->get('category')));
$link->save();
$tags = $request->input('tags');
$link->tags()->sync($tags);
return \Redirect::route('link.show',
array($link->slug))->with('message', 'Your link has been updated!');
}
Finally, update the particular select element you are interested in to have an id which the
select2 plugin can target. We used prettify as the id, so we can apply it to our select like
so:
<div class="form-group">
{!! Form::label('tags', 'Choose at least one tag') !!}
{!! Form::select('tags[]', $tags, null, ['class' => 'form-control input-lg', 'multiple', 'id' =>
'prettify', 'data-placeholder' => 'Choose at least one tag']) !!}
</div>
Of course this is simply a quick and dirty way to get this running with minimal effort. It may
be best to use Gulp and Elixir when actually deploying this to production to handle asset
compilation and minification.
With this simple addition, we can see that our tags now look ridiculously awesome!
In addition, it may be helpful to have a look at the source code of the relevant methods we
used in this tutorial.
lists()
public function lists($column, $key = null)
{
$results = $this->query->lists($column, $key);
// If the model has a mutator for the requested column, we will spin through
// the results and mutate the values so that the mutated version of these
// columns are returned as you would expect from these Eloquent models.
if ($this->model->hasGetMutator($column)) {
foreach ($results as $key => &$value) {
$fill = [$column => $value];
$value = $this->model->newFromBuilder($fill)->$column;
}
}
return collect($results);
}
attach()
public function attach($id, array $attributes = [], $touch = true)
{
if ($id instanceof Model) {
$id = $id->getKey();
}
$query = $this->newPivotStatement();
if ($touch) {
$this->touchIfTouching();
}
}
sync()
public function sync($ids, $detaching = true)
{
$changes = [
'attached' => [], 'detached' => [], 'updated' => [],
];
// First we need to attach any of the associated models that are not currently
// in this joining table. We'll spin through the given IDs, checking to see
// if they exist in the array of current ones, and if not we will insert.
$current = $this->newPivotQuery()->lists($this->otherKey);
$records = $this->formatSyncList($ids);
// Next, we will take the differences of the currents and given IDs and detach
// all of the entities that exist in the "current" array but are not in the
// the array of the IDs given to the method which will complete the sync.
if ($detaching && count($detach) > 0) {
$this->detach($detach);
// Now we are finally ready to attach the new records. Note that we'll disable
// touching until after the entire operation is complete so we don't fire a
// ton of touch operations until we are totally done syncing the records.
$changes = array_merge(
$changes, $this->attachNew($records, $current, false)
);
if (count($changes['attached']) || count($changes['updated'])) {
$this->touchIfTouching();
}
return $changes;
}
2 use ArrayAccess;
3 use ArrayIterator;
4 use CachingIterator;
5 use JsonSerializable;
6 use IteratorAggregate;
7 use InvalidArgumentException;
8 use Illuminate\Contracts\Support\Jsonable;
9 use Illuminate\Contracts\Support\Arrayable;
So what do all these mean, and where do they come from? Well, let’s hit them one by one.
First up, we have use Countable;. With PHP Storm, we can use the handy tool “Go To
Declaration” to see.
This takes us to SPL.php and shows us the Countable Interface.
Pretty cool! We can see that The Countable interface is part of the Standard PHP Library
(SPL). By using this technique, we can decipher all of these use statements.
New Up A Collection
With our new found knowledge of this convenient helper function, let us now new up a
Laravel Collection for fun and profit.
$sites = collect([
'http://google.com',
'http://plus.google.com',
'http://facebook.com',
'http://twitter.com',
'http://search.twitter.com',
'http://apple.com'
]);
dd($sites);
/*
Collection {#110 ▼
#items: array:6 [▼
0 => "http://google.com"
1 => "http://plus.google.com"
2 => "http://facebook.com"
3 => "http://twitter.com"
4 => "http://search.twitter.com"
5 => "http://apple.com"
]
}
*/
As you can see, we now have a collection that we can work with. One of the first things to
be explained in the documentation is how to map over each element in the collection and
apply a function to it while rejecting values that do not specify a certain criteria. Using this
example, let's have a look at our own collection of sites. We will change the format of all
url's to include a www prefix while removing any url that contains the word facebook. Let's
try it.
$sites = collect([
'http://google.com',
'http://plus.google.com',
'http://facebook.com',
'http://twitter.com',
'http://search.twitter.com',
'http://apple.com'
])->map(function ($site) {
return str_replace('http://', 'http://www.', $site);
})->reject(function ($site) {
return str_contains($site, 'facebook') == true;
});
dd($sites);
/*
Collection {#113 ▼
#items: array:5 [▼
0 => "http://www.google.com"
1 => "http://www.plus.google.com"
3 => "http://www.twitter.com"
4 => "http://www.search.twitter.com"
5 => "http://www.apple.com"
]
}
*/
Cool! Note that in this iteration, we make use of the fluent interface. What does it mean to
be fluent? All that means is you can chain together commands to get to the desired result.
It’s kind of like chaining methods in jQuery. We apply two methods to the collection to
achieve our desired result. map and reject. Inside the map iteration, we apply
the str_replace function to each collection element, stripping the http:// and replacing
with http://www. During the reject iteration we use the Laravel helper
method str_contains to filter out any elements that contain the word facebook. Note that
the expression must be equal to true in order for the reject method to eliminate the
element. So we can almost read this as, if string contains facebook then reject it. We can
see from the screenshot above that we did get our desired result.
1. all()
The Collection class has a protected property named $items which holds an array. This is
what the Collection is built up from. The all() method simply returns that property. This is
handy if you want to change a Laravel collection into a native PHP array.
public function all()
{
return $this->items;
}
Testing this on our own little collection, we can see that we are returned the array from
which the collection is based like so.
$sites = collect([
'http://google.com',
'http://plus.google.com',
'http://facebook.com',
'http://twitter.com',
'http://search.twitter.com',
'http://apple.com'
]);
$all = $sites->all();
dd($all);
/*
array:6 [▼
0 => "http://google.com"
1 => "http://plus.google.com"
2 => "http://facebook.com"
3 => "http://twitter.com"
4 => "http://search.twitter.com"
5 => "http://apple.com"
]
*/
2. avg()
The avg method does exactly what you think it would do, it calculates the average of a
collection. Here is the code which powers it.
public function avg($key = null)
{
if ($count = $this->count()) {
return $this->sum($key) / $count;
}
}
//852.33333333333
You can also provide a key for which to apply the average to. In the example of an
associative array, you would need to do this.
$avg = collect([
['size' => 'tall', 'price' => 2.50],
['size' => 'grande', 'price' => 3.45],
['size' => 'venti', 'price' => 4.75]
])->avg('price');
dd($avg);
// 3.5666666666667
3. chunk()
I never found much use for chunk until I actually read the documentation, which has a
great use case. As you would expect, chunk takes a group of things and breaks that group
down into smaller groups. The use case the documentation mentions is dealing with a
Bootstrap grid for example. If you’ve ever had a grid full of items, and find yourself looping
through a result set and then checking the value of an iterator in order to determine where
to terminate a row – this one is for you! In fact this one is for me, since I do this all the time!
Instead of troubling yourself with this, just use chunk() instead. This is how it works.
public function chunk($size)
{
$chunks = [];
foreach (array_chunk($this->items, $size, true) as $chunk) {
$chunks[] = new static($chunk);
}
return new static($chunks);
}
])->chunk(2);
dd($chunk);
/*
Collection {#120 ▼
#items: array:3 [▼
0 => Collection {#117 ▼
#items: array:2 [▼
0 => {#110 ▼
+"site": "google.com"
}
1 => {#111 ▼
+"site": "facebook.com"
}
]
}
1 => Collection {#118 ▼
#items: array:2 [▼
2 => {#112 ▼
+"site": "yahoo.com"
}
3 => {#113 ▼
+"site": "digg.com"
}
]
}
2 => Collection {#119 ▼
#items: array:2 [▼
4 => {#114 ▼
+"site": "twitter.com"
}
5 => {#115 ▼
+"site": "moz.com"
}
]
}
]
}
*/
When looping over chunked results, note that you will need a nested foreach since you
now have a collection, of smaller collections. So you need to loop through each chunk,
then loop through the contents of each chunk individually.
foreach ($chunk as $chunk) {
foreach ($chunk as $chunk) {
echo $chunk->site.'<br>';
}
}
// google.com
// facebook.com
// yahoo.com
// digg.com
// twitter.com
// moz.com
4. collapse()
This method makes use of a static method call as we see here.
public function collapse()
{
return new static(Arr::collapse($this->items));
}
/*
Collection {#110 ▼
#items: array:3 [▼
0 => array:3 [▼
"color" => "blue"
0 => 4
1 => 2
]
1 => array:5 [▼
0 => "x"
1 => "y"
"color" => "red"
"shape" => "circle"
2 => 300
]
2 => array:2 [▼
"make" => "Acura"
"type" => "NSX"
]
]
}
*/
5. contains()
How many times do you need to check if an array contains a value? All the time, am I
right?! The handy contains method on Laravel Collections makes it easy to do when
working with an array that has been collectionified.
The contains code.
public function contains($key, $value = null)
{
if (func_num_args() == 2) {
return $this->contains(function ($k, $item) use ($key, $value) {
return data_get($item, $key) == $value;
});
}
if ($this->useAsCallable($key)) {
return ! is_null($this->first($key));
}
First off, we can see the code makes use of the native PHP func_get_args().
The data_get() method is a custom helper method in the illuminate framework. Finally, we
can see in_array() being put to use. Visit each of the prior links in turn to make sure you
understand each step of the process.
Testing out contains() with the following collection.
$collection = collect([
'color' => 'blue',
4,
2,
'x',
'y',
'shape' => 'circle',
300,
'make' => 'Acura',
'type' => 'NSX'
]);
dd($collection->contains('color'));
// false
It appears the contains method is only checking the value, not the key of the collection.
dd($collection->contains('color', ''));
// true
By passing an empty string as the second parameter, you can check for the existence of a
specific key.
$collection = collect([
[
'color' => 'blue',
4,
2,
'xray',
'y',
'shape' => 'circle',
300,
'make' => 'Acura',
'type' => 'NSX'
]
]);
dd($collection->contains('make', 'Acura'));
// true
You may pass in two parameters in a case sensitive manner to check for the existence of
a key value pair. Note that this only pertains to nested collections, so the snippet above
works, but the snippet below does not.
$collection = collect([
'color' => 'blue',
4,
2,
'xray',
'y',
'shape' => 'circle',
300,
'make' => 'Acura',
'type' => 'NSX'
]);
dd($collection->contains('make', 'Acura'));
// false
To get a little more granular, you can just make use of your own callback function. Check it
out.
$collection = collect([
'color' => 'blue',
4,
2,
'xray',
'y',
'shape' => 'circle',
300,
'make' => 'Acura',
'type' => 'NSX'
]);
dd($result);
// true
There is no key by the name of hiphop in our collection. We do however have an NSX
value in the collection, hence the truthy return. This also allows us to search for a key
value pair in a flat collection like so.
$collection = collect([
'color' => 'blue',
4,
2,
'xray',
'y',
'shape' => 'circle',
300,
'make' => 'Acura',
'type' => 'NSX'
]);
dd($result);
// true
6. count()
Simple but useful, count does precisely what it says, it counts the number of items in the
collection. How does it work? Just like so.
public function count()
{
return count($this->items);
}
The method uses the native PHP count() function. So in the Laravel Collection class, we
simply look at the $items property, and return the number of items in it. Observe our
example.
$collection = collect([
'color' => 'blue',
'size' => 'extra large',
'comedian' => 'Seinfeld',
'search engine' => 'google'
]);
dd($collection->count());
// 4
7. diff()
This method makes use of array_diff() to compare arrays. This is the code that makes it
work.
public function diff($items)
{
return new static(array_diff($this->items, $this->getArrayableItems($items)));
}
For example, imagine a candidate has an array of companies she would like to work for.
She needs to compare this against an array of companies that are currently not hiring,
then try to interview with only those that are hiring. How might she do this?
$want = collect(['Apple', 'Google', 'Twitter', 'Cisco', 'Dell', 'HP']);
$nothiring = collect(['Apple', 'Google']);
$interview = $want->diff($nothiring);
dd($interview);
// Twitter, Cisco, Dell, HP
8. each()
This method allows you to apply a callback to every item in the collection and is powered
with this code.
public function each(callable $callback)
{
foreach ($this->items as $key => $item) {
if ($callback($item, $key) === false) {
break;
}
}
return $this;
}
For an example we will have a collection of numbers. As long as the number is less than 5,
then we will use a callback to square it.
$collection = collect([1, 2, 3, 4, 5, 6, 7, 8, 9]);
$collection->each(function ($value) {
if ($value > 5) {
return false;
}
echo $value * $value . '<br>';
});
// 1
// 4
// 9
// 16
// 25
The same result with a foreach would be carried out like so:
$collection = collect([1, 2, 3, 4, 5, 6, 7, 8, 9]);
So you see, each() just adds some sugar so you can code in a more modern style if you
prefer. Pick your poison.
9. every()
This interesting method peeks into your collection and creates a new collection on every
n’th element which you specify. The source is here.
public function every($step, $offset = 0)
{
$new = [];
$position = 0;
$position++;
}
dd($collection->every(2));
/*
Collection {#111 ▼
#items: array:3 [▼
0 => array:3 [▼
0 => "red"
1 => "green"
2 => "blue"
]
1 => array:3 [▼
0 => "yaba"
1 => "daba"
2 => "doo"
]
2 => array:3 [▼
0 => "meat"
1 => "potatoes"
2 => "gravy"
]
]
}
*/
10. filter()
The filter method is another one which allows you to apply a callback to the collection,
retaining only the items that pass a test of your choice. The code which makes it happen is
here.
public function filter(callable $callback = null)
{
if ($callback) {
return new static(array_filter($this->items, $callback));
}
As we can see it makes use of the native PHP function array_filter(). Taking the filter
method for a test drive gives us these results.
$collection = collect([
['red', 'green', 'blue'],
['apple', 'orange', 'lemon'],
['yaba', 'daba', 'doo'],
['hip', 'hop', 'hooray'],
['meat', 'potatoes', 'gravy'],
['apple pie', 'pumpkin latte', 'apple cider'],
]);
dd($filterized);
/*
Collection {#112 ▼
#items: array:1 [▼
1 => array:3 [▼
0 => "apple"
1 => "orange"
2 => "lemon"
]
]
}
*/
Here, we basically say, only return the items which contain the string of ‘lemon’, and in fact
this is exactly what we get.
11. first()
The first() method returns the first item in the collection. The source code for this method is
here.
public function first(callable $callback = null, $default = null)
{
if (is_null($callback)) {
return count($this->items) > 0 ? reset($this->items) : null;
}
return Arr::first($this->items, $callback, $default);
}
$first = $collection->first();
dd($first);
*/
array:3 [▼
0 => "sunshine"
1 => "blue sky"
2 => "blue water"
]
*/
As we can see in this example, the very first item in the collection which is an array, is
returned to us. This method also allows you to specify a condition or truth test so you can
return the first item that passes that test. In this next snippet we will check if an item is a
string, and if so, return it.
$collection = collect([
['sunshine', 'blue sky', 'blue water'],
['apple pie', 'yellow', 'black roof'],
[1, 2, 3],
'random stuff',
'not a number',
['apple crisp', 'jackolantern'],
]);
dd($first);
// random stuff
12. flatten()
If you have a heavily nested multi dimensional array, you can use flatten() to turn it into a
single dimension array. Consider this collection.
$collection = collect([
'mobile' => 'iPhone',
'grub' => ['restaurant' => 'Chipoltle', 'meal' => 'burrito'],
['editor' => ['vendor' => 'jetbrains', 'ide' => 'phpstorm']]
]);
Before flatten()
dd($collection);
/*
Collection {#110 ▼
#items: array:3 [▼
"mobile" => "iPhone"
"grub" => array:2 [▼
"restaurant" => "Chipoltle"
"meal" => "burrito"
]
0 => array:1 [▼
"editor" => array:2 [▼
"vendor" => "jetbrains"
"ide" => "phpstorm"
]
]
]
}
*/
After flatten()
dd($collection->flatten());
/*
Collection {#111 ▼
#items: array:5 [▼
0 => "iPhone"
1 => "Chipoltle"
2 => "burrito"
3 => "jetbrains"
4 => "phpstorm"
]
}
*/
return $return;
}
dd($collection->flip());
We see this can only operate on string or integer values, so let’s give both of those a shot.
$collection = collect([
'mobile' => 'iPhone',
'integer' => 10,
'string' => 'all day',
'another integer' => 20
]);
dd($collection->flip());
/*
Collection {#111 ▼
#items: array:4 [▼
"iPhone" => "mobile"
10 => "integer"
"all day" => "string"
20 => "another integer"
]
}
*/
dd($collection->forget('string'));
/*
Collection {#110 ▼
#items: array:3 [▼
"mobile" => "iPhone"
"integer" => 10
"another integer" => 20
]
}
*/
return $this;
}
15. forPage()
This interesting method makes use of array_slice() as we can see by doing some detective
work on the Collection class file below.
public function forPage($page, $perPage)
{
return $this->slice(($page - 1) * $perPage, $perPage);
}
What it does is pretty cool. In a large result set that may be paginated, you can fetch the
items from any page of the results. Say you have 5 pages of 5 items each. You could
specify that you only want the results which would appear on page 3. Let’s see how to do
that.
$collection = collect([
['url' => 'google.com'],
['url' => 'facebook.com'],
['url' => 'amazon.com'],
['url' => 'youtube.com'],
['url' => 'yahoo.com'],
['url' => 'wikipedia.org'],
['url' => 'ebay.com'],
['url' => 'twitter.com'],
['url' => 'craigslist.com'],
['url' => 'reddit.com'],
['url' => 'netflix.com'],
['url' => 'linkedin.com'],
['url' => 'bing.com'],
['url' => 'pinterest.com'],
['url' => 'apple.com'],
['url' => 'instagram.com'],
['url' => 'msn.com'],
['url' => 'walmart.com'],
['url' => 'yelp.com'],
['url' => 'weather.com'],
['url' => 'zillow.com'],
['url' => 'wordpress.com'],
['url' => 'target.com'],
['url' => 'buzzfeed.com'],
['url' => 'microsoft.com'],
]);
dd($collection->forPage(3, 5));
/*
Collection {#111 ▼
#items: array:5 [▼
10 => array:1 [▼
"url" => "netflix.com"
]
11 => array:1 [▼
"url" => "linkedin.com"
]
12 => array:1 [▼
"url" => "bing.com"
]
13 => array:1 [▼
"url" => "pinterest.com"
]
14 => array:1 [▼
"url" => "apple.com"
]
]
}
*/
Very Cool!
16. get()
This is one of those methods you’ve been using all along without even thinking about it.
get() simply gets the item you specify by key and returns null if the key is not there. It is
powered via the following source code and makes use of the native
PHP array_key_exists() function.
public function get($key, $default = null)
{
if ($this->offsetExists($key)) {
return $this->items[$key];
}
return value($default);
}
Consider the prior example where we had a list of 25 urls. The collection consisted of an
array or arrays. Every inner array uses ‘url’ as it’s key, so we can’t get by that. We can
however provide an integer, and that will get the item indexed at that value. Let’s try to get
apple.com from our prior example.
dd($collection->get(14));
/*
array:1 [▼
"url" => "apple.com"
]
*/
Bingo – it works. A simpler example might be something like this.
$collection = collect([
'mobile' => 'iPhone',
'integer' => 10,
'string' => 'all day',
'another integer' => 20
]);
dd($collection->get('mobile'));
// iPhone
17. groupBy()
You can pass a string or a callback to the groupBy method, and it will return to you the
results, grouped by that value. Let’s test this out using the string approach. We will
reconfigure our list of urls and change each key so that we have each url belonging to a
certain type of category. They we can use the groupBy method to get by category.
$collection = collect([
['search' => 'google.com'],
['social' => 'facebook.com'],
['shopping' => 'amazon.com'],
['entertainment' => 'youtube.com'],
['entertainment' => 'yahoo.com'],
['info' => 'wikipedia.org'],
['shopping' => 'ebay.com'],
['social' => 'twitter.com'],
['info' => 'craigslist.com'],
['entertainment' => 'reddit.com'],
['entertainment' => 'netflix.com'],
['career' => 'linkedin.com'],
['search' => 'bing.com'],
['entertainment' => 'pinterest.com'],
['shopping' => 'apple.com'],
['social' => 'instagram.com'],
['info' => 'msn.com'],
['shopping' => 'walmart.com'],
['info' => 'yelp.com'],
['info' => 'weather.com'],
['shopping' => 'zillow.com'],
['blogging' => 'wordpress.com'],
['shopping' => 'target.com'],
['entertainment' => 'buzzfeed.com'],
['software' => 'microsoft.com'],
]);
dd($collection->groupBy('entertainment'));
/*
Collection {#119 ▼
#items: array:7 [▼
"" => Collection {#112 ▼
#items: array:19 [▼
0 => array:1 [▼
"search" => "google.com"
]
1 => array:1 [▼
"social" => "facebook.com"
]
2 => array:1 [▼
"shopping" => "amazon.com"
]
3 => array:1 [▼
"info" => "wikipedia.org"
]
4 => array:1 [▼
"shopping" => "ebay.com"
]
5 => array:1 [▼
"social" => "twitter.com"
]
6 => array:1 [▼
"info" => "craigslist.com"
]
7 => array:1 [▼
"career" => "linkedin.com"
]
8 => array:1 [▼
"search" => "bing.com"
]
9 => array:1 [▼
"shopping" => "apple.com"
]
10 => array:1 [▼
"social" => "instagram.com"
]
11 => array:1 [▼
"info" => "msn.com"
]
12 => array:1 [▼
"shopping" => "walmart.com"
]
13 => array:1 [▼
"info" => "yelp.com"
]
14 => array:1 [▼
"info" => "weather.com"
]
15 => array:1 [▼
"shopping" => "zillow.com"
]
16 => array:1 [▼
"blogging" => "wordpress.com"
]
17 => array:1 [▼
"shopping" => "target.com"
]
18 => array:1 [▼
"software" => "microsoft.com"
]
]
}
"youtube.com" => Collection {#113 ▼
#items: array:1 [▼
0 => array:1 [▼
"entertainment" => "youtube.com"
]
]
}
"yahoo.com" => Collection {#114 ▼
#items: array:1 [▼
0 => array:1 [▼
"entertainment" => "yahoo.com"
]
]
}
"reddit.com" => Collection {#115 ▼
#items: array:1 [▼
0 => array:1 [▼
"entertainment" => "reddit.com"
]
]
}
"netflix.com" => Collection {#116 ▼
#items: array:1 [▼
0 => array:1 [▼
"entertainment" => "netflix.com"
]
]
}
"pinterest.com" => Collection {#117 ▼
#items: array:1 [▼
0 => array:1 [▼
"entertainment" => "pinterest.com"
]
]
}
"buzzfeed.com" => Collection {#118 ▼
#items: array:1 [▼
0 => array:1 [▼
"entertainment" => "buzzfeed.com"
]
]
}
]
}
*/
dd($collection->groupBy('shopping'));
/*
Collection {#119 ▼
#items: array:7 [▼
"" => Collection {#112 ▼
#items: array:19 [▼
0 => array:1 [▼
"search" => "google.com"
]
1 => array:1 [▼
"social" => "facebook.com"
]
2 => array:1 [▼
"entertainment" => "youtube.com"
]
3 => array:1 [▼
"entertainment" => "yahoo.com"
]
4 => array:1 [▼
"info" => "wikipedia.org"
]
5 => array:1 [▼
"social" => "twitter.com"
]
6 => array:1 [▼
"info" => "craigslist.com"
]
7 => array:1 [▼
"entertainment" => "reddit.com"
]
8 => array:1 [▼
"entertainment" => "netflix.com"
]
9 => array:1 [▼
"career" => "linkedin.com"
]
10 => array:1 [▼
"search" => "bing.com"
]
11 => array:1 [▼
"entertainment" => "pinterest.com"
]
12 => array:1 [▼
"social" => "instagram.com"
]
13 => array:1 [▼
"info" => "msn.com"
]
14 => array:1 [▼
"info" => "yelp.com"
]
15 => array:1 [▼
"info" => "weather.com"
]
16 => array:1 [▼
"blogging" => "wordpress.com"
]
17 => array:1 [▼
"entertainment" => "buzzfeed.com"
]
18 => array:1 [▼
"software" => "microsoft.com"
]
]
}
"amazon.com" => Collection {#113 ▼
#items: array:1 [▼
0 => array:1 [▼
"shopping" => "amazon.com"
]
]
}
"ebay.com" => Collection {#114 ▼
#items: array:1 [▼
0 => array:1 [▼
"shopping" => "ebay.com"
]
]
}
"apple.com" => Collection {#115 ▼
#items: array:1 [▼
0 => array:1 [▼
"shopping" => "apple.com"
]
]
}
"walmart.com" => Collection {#116 ▼
#items: array:1 [▼
0 => array:1 [▼
"shopping" => "walmart.com"
]
]
}
"zillow.com" => Collection {#117 ▼
#items: array:1 [▼
0 => array:1 [▼
"shopping" => "zillow.com"
]
]
}
"target.com" => Collection {#118 ▼
#items: array:1 [▼
0 => array:1 [▼
"shopping" => "target.com"
]
]
}
]
}
*/
I always found groupBy type operations to be a little tricky and hard to predict. The source
code shows that this is indeed a bit of a more complex operation.
public function groupBy($groupBy, $preserveKeys = false)
{
$groupBy = $this->valueRetriever($groupBy);
$results = [];
if (! array_key_exists($groupKey, $results)) {
$results[$groupKey] = new static;
}
18. has()
We now have a simple one following the more complex example just above. Need to
check if a key exists in your collection? Simple, just use has().
$collection = collect([
'search' => 'google.com',
'social' => 'facebook.com',
'shopping' => 'amazon.com',
'entertainment' => 'youtube.com',
'info' => 'wikipedia.org',
'career' => 'linkedin.com',
'blogging' => 'wordpress.com',
'software' => 'microsoft.com'
]);
dd($collection->has('software'));
// true
The source shows us how this works.
public function has($key)
{
return $this->offsetExists($key);
}
19. implode()
You’re probably used to taking an array in native PHP and imploding it into a list or line of
items separated by some random character or group of characters. You can do the same
thing to your collections with this method. Let’s see an example.
$collection = collect([
['weather' => 'sunshine', 'activity' => 'swimming'],
['weather' => 'cloudy', 'activity' => 'working'],
['weather' => 'snow', 'activity' => 'skiing'],
['weather' => 'rain', 'activity' => 'coding'],
]);
It works just like you think it would, making use of the native PHP implode().
public function implode($value, $glue = null)
{
$first = $this->first();
if (is_array($first) || is_object($first)) {
return implode($glue, $this->pluck($value)->all());
}
dd($collection1->intersect($collection2));
/*
Collection {#112 ▼
#items: array:2 [▼
4 => 5
5 => 6
]
}
*/
21. isEmpty()
Many times a collection is passed to a view, and you do not want to try to loop through it if
it is empty. This handy method lets us know right away whether or not a collection even
has anything inside of it. Let’s see how it works.
$collection1 = collect([1, 2, 3, 4, 5, 6]);
$collection2 = collect([]);
dd($collection1->isEmpty());
// false
dd($collection2->isEmpty());
// true
$results = [];
Once again we see that reference to the data_get() method, and it’s a bit of a doozy so
let’s inspect it.
function data_get($target, $key, $default = null)
{
if (is_null($key)) {
return $target;
}
$target = $target[$segment];
} elseif ($target instanceof ArrayAccess) {
if (! isset($target[$segment])) {
return value($default);
}
$target = $target[$segment];
} elseif (is_object($target)) {
if (! isset($target->{$segment})) {
return value($default);
}
$target = $target->{$segment};
} else {
return value($default);
}
}
return $target;
}
This method looks to be one of the workhorses of the Collection class, and as we can see
makes use of is_null(), is_array(), array_key_exists(), isset(), and is_object() among
others.
An example of how keyBy() works shows that you can set the keys of the collection by the
key provided to keyBy(). Observe.
$collection = collect([
['url' => 'google.com'],
['url' => 'facebook.com'],
['url' => 'amazon.com'],
['url' => 'youtube.com'],
['url' => 'yahoo.com'],
['url' => 'wikipedia.org'],
['url' => 'ebay.com'],
['url' => 'twitter.com'],
['url' => 'craigslist.com'],
['url' => 'reddit.com'],
['url' => 'netflix.com'],
['url' => 'linkedin.com'],
['url' => 'bing.com'],
['url' => 'pinterest.com'],
['url' => 'apple.com'],
['url' => 'instagram.com'],
['url' => 'msn.com'],
['url' => 'walmart.com'],
['url' => 'yelp.com'],
['url' => 'weather.com'],
['url' => 'zillow.com'],
['url' => 'wordpress.com'],
['url' => 'target.com'],
['url' => 'buzzfeed.com'],
['url' => 'microsoft.com'],
]);
dd($collection->keyBy('url'));
/*
Collection {#112 ▼
#items: array:25 [▼
"google.com" => array:1 [▼
"url" => "google.com"
]
"facebook.com" => array:1 [▼
"url" => "facebook.com"
]
"amazon.com" => array:1 [▼
"url" => "amazon.com"
]
"youtube.com" => array:1 [▼
"url" => "youtube.com"
]
"yahoo.com" => array:1 [▼
"url" => "yahoo.com"
]
"wikipedia.org" => array:1 [▼
"url" => "wikipedia.org"
]
"ebay.com" => array:1 [▼
"url" => "ebay.com"
]
"twitter.com" => array:1 [▼
"url" => "twitter.com"
]
"craigslist.com" => array:1 [▼
"url" => "craigslist.com"
]
"reddit.com" => array:1 [▼
"url" => "reddit.com"
]
"netflix.com" => array:1 [▼
"url" => "netflix.com"
]
"linkedin.com" => array:1 [▼
"url" => "linkedin.com"
]
"bing.com" => array:1 [▼
"url" => "bing.com"
]
"pinterest.com" => array:1 [▼
"url" => "pinterest.com"
]
"apple.com" => array:1 [▼
"url" => "apple.com"
]
"instagram.com" => array:1 [▼
"url" => "instagram.com"
]
"msn.com" => array:1 [▼
"url" => "msn.com"
]
"walmart.com" => array:1 [▼
"url" => "walmart.com"
]
"yelp.com" => array:1 [▼
"url" => "yelp.com"
]
"weather.com" => array:1 [▼
"url" => "weather.com"
]
"zillow.com" => array:1 [▼
"url" => "zillow.com"
]
"wordpress.com" => array:1 [▼
"url" => "wordpress.com"
]
"target.com" => array:1 [▼
"url" => "target.com"
]
"buzzfeed.com" => array:1 [▼
"url" => "buzzfeed.com"
]
"microsoft.com" => array:1 [▼
"url" => "microsoft.com"
]
]
}
*/
23. keys()
This handy method gives you the ability to fetch only the keys of the collection. Let’s test it
out on one of our mixed type collections.
$collection = collect([
['google' => 'alphabet', 4, 2],
'four' => 4,
1234,
'name' => 'Jim',
['xray', 'redsox', 'color' => 'green', 'shape' => 'perfect circle', 500],
['make' => 'Acura', 'type' => 'NSX'],
'weather' => 'sunny',
'play' => 'videogames',
'object' => (object)['soup' => 'french onion']
]);
dd($collection->keys());
/*
Collection {#112 ▼
#items: array:9 [▼
0 => 0
1 => "four"
2 => 1
3 => "name"
4 => 2
5 => 3
6 => "weather"
7 => "play"
8 => "object"
]
}
*/
24. last()
If you would like access to the last item in the collection, you can use the aptly named
last() method. A few examples are in order. First we will pass no argument, which simply
grabs the last item in the collection no matter what. The second example will use a
callback to find the first item starting from the end of the collection that matches a given
test.
$collection = collect([
['url' => 'google.com'],
['url' => 'facebook.com'],
['url' => 'amazon.com'],
['url' => 'youtube.com'],
['url' => 'yahoo.com'],
['url' => 'wikipedia.org'],
['url' => 'ebay.com'],
['url' => 'twitter.com'],
['url' => 'craigslist.com'],
['url' => 'reddit.com'],
['url' => 'netflix.com'],
['url' => 'linkedin.com'],
['url' => 'bing.com'],
['url' => 'pinterest.com'],
['url' => 'apple.com'],
['url' => 'instagram.com'],
['url' => 'msn.com'],
['url' => 'walmart.com'],
['url' => 'yelp.com'],
['url' => 'weather.com'],
['url' => 'zillow.com'],
['url' => 'wordpress.com'],
['url' => 'target.com'],
['url' => 'buzzfeed.com'],
['url' => 'microsoft.com'],
]);
dd($collection->last());
25. map()
With this method we can iterate across the collection and pass each item to a callback
which can modify it. Let’s see how it works.
$collection = collect([
['url' => 'etsy.com'],
['url' => 'aol.com'],
['url' => 'diply.com'],
['url' => 'foxnews.com'],
['url' => 'bestbuy.com'],
]);
dd($collection->map(function ($item){
return strrev($item['url']);
}));
/*
Collection {#112 ▼
#items: array:5 [▼
0 => "moc.yste"
1 => "moc.loa"
2 => "moc.ylpid"
3 => "moc.swenxof"
4 => "moc.yubtseb"
]
}
*/
Here is the source for map() which makes use of array_keys() and array_map().
public function map(callable $callback)
{
$keys = array_keys($this->items);
26. merge()
We can see that merge() makes use of array_merge() here.
public function merge($items)
{
return new static(array_merge($this->items, $this->getArrayableItems($items)));
}
$collection2 = collect([
['url' => 'wikia.com'],
['url' => 'indeed.com'],
['url' => 'usps.com'],
['url' => 'capitalone.com'],
['url' => 'att.com'],
]);
dd($collection1->merge($collection2));
/*
Collection {#112 ▼
#items: array:10 [▼
0 => array:1 [▼
"url" => "comcast.net"
]
1 => array:1 [▼
"url" => "nfl.com"
]
2 => array:1 [▼
"url" => "washingtonpost.com"
]
3 => array:1 [▼
"url" => "homedepot.com"
]
4 => array:1 [▼
"url" => "microsoftonline.com"
]
5 => array:1 [▼
"url" => "wikia.com"
]
6 => array:1 [▼
"url" => "indeed.com"
]
7 => array:1 [▼
"url" => "usps.com"
]
8 => array:1 [▼
"url" => "capitalone.com"
]
9 => array:1 [▼
"url" => "att.com"
]
]
}
*/
27. pluck()
One of my favorites is the pluck method which allows you to get all of the values for a
provided key in the collection. Let’s test it out.
$collection = collect([
['url' => 'comcast.net', 'industry' => 'telecom'],
['url' => 'nfl.com', 'industry' => 'entertainment'],
['url' => 'washingtonpost.com', 'industry' => 'news'],
['url' => 'homedepot.com', 'industry' => 'homebuilders'],
['url' => 'microsoftonline.com', 'industry' => 'software'],
]);
dd($collection->pluck('industry'));
/*
Collection {#111 ▼
#items: array:5 [▼
0 => "telecom"
1 => "entertainment"
2 => "news"
3 => "homebuilders"
4 => "software"
]
}
*/
// If the key is "null", we will just append the value to the array and keep
// looping. Otherwise we will key the array using the value of the key we
// received from the developer. Then we'll return the final array form.
if (is_null($key)) {
$results[] = $itemValue;
} else {
$itemKey = data_get($item, $key);
$results[$itemKey] = $itemValue;
}
}
return $results;
}
28. pop()
Pop goes the weasel right off the end of the collection. In other words, pop() removes the
last item from the collection.
$collection = collect([
['url' => 'americanexpress.com'],
['url' => 'pandora.com'],
['url' => 'ask.com'],
['url' => 'groupon.com'],
['url' => 'hulu.com'],
]);
dd($collection->pop());
We can see the use of array_pop() to help us out from the source.
public function pop()
{
return array_pop($this->items);
}
29. prepend()
In order to add something to the beginning of an array, we usually use array_unshift(). The
prepend() method uses a much friendlier name to give us an indication of what it will do.
Testing it out gives us these results.
$collection = collect([
['url' => 'ups.com'],
['url' => 'dropbox.com'],
['url' => 'verizonwireless.com'],
['url' => 'usatoday.com'],
['url' => 'answers.com'],
]);
/*
Collection {#110 ▼
#items: array:6 [▼
0 => array:1 [▼
"url" => "vegibit.com"
]
1 => array:1 [▼
"url" => "ups.com"
]
2 => array:1 [▼
"url" => "dropbox.com"
]
3 => array:1 [▼
"url" => "verizonwireless.com"
]
4 => array:1 [▼
"url" => "usatoday.com"
]
5 => array:1 [▼
"url" => "answers.com"
]
]
}
*/
A quick source inspection does confirm the use of array_unshift() for us.
public function prepend($value)
{
array_unshift($this->items, $value);
return $this;
}
30. pull()
Let’s put pull() to the test straight away.
$collection = collect([
'url' => 'cnet.com', 'industry' => 'tech news', 'reviews' => true
]);
dd($collection->pull('industry'));
// "tech news"
dd($collection);
*/
Collection {#110 ▼
#items: array:2 [▼
"url" => "cnet.com"
"reviews" => true
]
}
*/
pull() takes an item out of the collection and returns it to you based on the key you provide
to it. It uses this code to work it’s magic.
public function pull($key, $default = null)
{
return Arr::pull($this->items, $key, $default);
}
public static function pull(&$array, $key, $default = null)
{
$value = static::get($array, $key, $default);
static::forget($array, $key);
return $value;
}
31. push()
Again you are most likely familiar with array_push() to put things on the end of an array.
The laravel push() method allows us to put things on the end of a collection. Would you
like to see?
$collection = collect([
['url' => 'forbes.com'],
['url' => 'stackoverflow.com'],
['url' => 'office.com'],
]);
/*
Collection {#110 ▼
#items: array:4 [▼
0 => array:1 [▼
"url" => "forbes.com"
]
1 => array:1 [▼
"url" => "stackoverflow.com"
]
2 => array:1 [▼
"url" => "office.com"
]
3 => array:1 [▼
"url" => "adobe.com"
]
]
}
*/
32. put()
put() is almost like push() with a slightly different implementation. With put(), it also uses
the offsetSet() method, but uses a different signature.
public function put($key, $value)
{
$this->offsetSet($key, $value);
return $this;
}
/*
Collection {#110 ▼
#items: array:3 [▼
0 => array:1 [▼
"url" => "macys.com"
]
1 => array:1 [▼
"was put" => "clobbered"
]
2 => array:1 [▼
"url" => "fedex.com"
]
]
}
*/
By this example, you can see that we can overwrite existing values anywhere in the
collection if we like – or simply add a new item both key and value altogether.
33. random()
random() allows us to reach into the collection and pull out a completely unpredictable and
random item. A quick look at the source shows us how it completes this task.
public function random($amount = 1)
{
if ($amount > ($count = $this->count())) {
throw new InvalidArgumentException("You requested {$amount} items, but there are only
{$count} items in the collection");
}
if ($amount == 1) {
return $this->items[$keys];
}
You have a fair bit of logic happening there between the use
of array_rand(), array_intersect_key(), and array_flip(). Let’s test it out.
$collection = collect([
['url' => 'slickdeals.net'],
['url' => 'mlb.com'],
['url' => 'amazonaws.com'],
['url' => 'twitch.tv'],
['url' => 'lowes.com'],
['url' => 'webmd.com'],
['url' => 'businessinsider.com'],
['url' => 'bleacherreport.com'],
['url' => 'salesforce.com'],
['url' => 'bbc.com'],
['url' => 'github.com'],
['url' => 'gap.com'],
]);
dd($collection->random());
// 101480
35. reject()
We saw an example of this method at the beginning of the article when we rejected any url
from the collection with a string value of facebook within it. Let’s look at the source to see
how this works.
public function reject($callback)
{
if ($this->useAsCallable($callback)) {
return $this->filter(function ($item) use ($callback) {
return ! $callback($item);
});
}
Testing it out again, and this time we will reject any item in the collection that contains the
string ‘discover’.
$collection = collect([
'http://wsj.com',
'http://discovercard.com',
'http://realtor.com',
'http://theguardian.com',
'http://newegg.com',
'http://nbcnews.com'
])->reject(function ($site) {
return str_contains($site, 'discover') == true;
});
dd($collection);
/*
Collection {#113 ▼
#items: array:5 [▼
0 => "http://wsj.com"
2 => "http://realtor.com"
3 => "http://theguardian.com"
4 => "http://newegg.com"
5 => "http://nbcnews.com"
]
}
*/
36. reverse()
The reverse() method does what you expect and that is to reverse the order of the items in
the collection. It does so using array_reverse() as we can see here.
public function reverse()
{
return new static(array_reverse($this->items));
}
Don’t forget, all of these methods are fluent so let’s remind ourselves of that now.
$collection = collect([
'http://wsj.com',
'http://discovercard.com',
'http://realtor.com',
'http://theguardian.com',
'http://newegg.com',
'http://nbcnews.com'
])->reverse();
dd($collection);
/*
Collection {#111 ▼
#items: array:6 [▼
5 => "http://nbcnews.com"
4 => "http://newegg.com"
3 => "http://theguardian.com"
2 => "http://realtor.com"
1 => "http://discovercard.com"
0 => "http://wsj.com"
]
}
37. search()
Conveniently enough, you can also search through a given laravel collection using the
handy search() method. It searched by value, and returns the key if found. The function
uses array_search() and call_user_func() functions to make the magic happen.
public function search($value, $strict = false)
{
if (! $this->useAsCallable($value)) {
return array_search($value, $this->items, $strict);
}
return false;
}
dd($collection);
// 5
// index 5 is the one that holds stackexhange.com
38. shift()
shift() is a nice little wrapper for array_shift() which grabs the first element off the start of
an array.
Does it work? You betcha. Again, note the fluent style.
public function shift()
{
return array_shift($this->items);
}
$collection = collect([
'Deviantart.com',
'Allrecipes.com',
'Retailmenot.com',
'Thesaurus.com',
])->shift();
dd($collection);
// Deviantart.com
39. shuffle()
Makes it convenient to use the fluent style via the built in PHP shuffle() function.
public function shuffle()
{
$items = $this->items;
shuffle($items);
dd($collection);
/*
Collection {#111 ▼
#items: array:9 [▼
0 => "Pch.com "
1 => "Blackboard.com"
2 => "People.com"
3 => "Goodreads.com"
4 => "Southwest.com"
5 => "Wunderground.com"
6 => "Drudgereport.com"
7 => "Ca.gov"
8 => "Npr.org"
]
}
*/
40. slice()
array_slice() is commonly used in many PHP projects. Laravel includes this in its collection
class via the following code.
public function slice($offset, $length = null, $preserveKeys = false)
{
return new static(array_slice($this->items, $offset, $length, $preserveKeys));
}
This method is very powerful. You are able to pass in a single value to determine where
the slice will begin. At that point, it will return the rest of the items in the collection
beginning from that point you provided. When I think of slice however, I usually think of it to
mean when you reach into an array or collection, and take out a specific number of items
at a specific starting point. You can do this as well with slice(), all you have to do is pass
the number of items you would like as the second argument. Finally, you also have the
option to either have brand new numeric based keys on the new slice, or the ability to
retain the original keys. Pass true as the third argument if you want to keep the original
keys in tact. Let’s test all three at once (note we pass all three parameters).
$collection = collect([
'Expedia.com' => 'Has fun commercials',
'Soundcloud.com' => 'Cool music website.',
'Intuit.com ' => 'Business software for all.',
'Patch.com' => 'local news',
'Trulia.com' => 'Search Real Estate',
'Accuweather.com' => 'Get the forecast',
'Staples.com' => 'buy some office supplies',
])->slice(3, 2, true);
dd($collection);
/*
Collection {#111 ▼
#items: array:2 [▼
"Patch.com" => "local news"
"Trulia.com" => "Search Real Estate"
]
}
*/
41. sort()
You can sort your collections using the sort() method. The Laravel code which powers it
uses uasort() as you can see here.
public function sort(callable $callback = null)
{
$items = $this->items;
if ($a == $b) {
return 0;
}
dd($collection);
/*
Collection {#111 ▼
#items: array:9 [▼
0 => 0
6 => 1
1 => 4
7 => 5
2 => 9
3 => 22
8 => 77
4 => 123
5 => 432
]
}
*/
42. sortBy()
This method is really handy to use with Eloquent, since we so often need to sort data from
a database. The source is involved, so take a few minutes to review.
public function sortBy($callback, $options = SORT_REGULAR, $descending = false)
{
$results = [];
$callback = $this->valueRetriever($callback);
// First we will loop through the items and get the comparator from a callback
// function which we were given. Then, we will sort the returned values and
// and grab the corresponding values for the sorted keys from this array.
foreach ($this->items as $key => $value) {
$results[$key] = $callback($value, $key);
}
// Once we have sorted all of the keys in the array, we will loop through them
// and grab the corresponding model so we can set the underlying items list
// to the sorted version. Then we'll just return the collection instance.
foreach (array_keys($results) as $key) {
$results[$key] = $this->items[$key];
}
dd($collection);
/*
Collection {#112 ▼
#items: array:7 [▼
6 => array:2 [▼
"url" => "Cbs.com"
"votes" => 1
]
3 => array:2 [▼
"url" => "Glassdoor.com"
"votes" => 5
]
1 => array:2 [▼
"url" => "Fidelity.com"
"votes" => 5
]
4 => array:2 [▼
"url" => "Sears.com"
"votes" => 10
]
0 => array:2 [▼
"url" => "Overstock.com"
"votes" => 15
]
2 => array:2 [▼
"url" => "Vimeo.com"
"votes" => 22
]
5 => array:2 [▼
"url" => "Ign.com "
"votes" => 31
]
]
}
*/
43. sortByDesc()
One of my personal favorites oddly enough, sort the results just like sortBy() but in the
opposite direction.
$collection = collect([
['url' => 'Overstock.com', 'votes' => 15],
['url' => 'Fidelity.com', 'votes' => 5],
['url' => 'Vimeo.com', 'votes' => 22],
['url' => 'Glassdoor.com', 'votes' => 5],
['url' => 'Sears.com', 'votes' => 10],
['url' => 'Ign.com ', 'votes' => 31],
['url' => 'Cbs.com', 'votes' => 1],
])->sortByDesc('votes');
dd($collection);
/*
Collection {#112 ▼
#items: array:7 [▼
5 => array:2 [▼
"url" => "Ign.com "
"votes" => 31
]
2 => array:2 [▼
"url" => "Vimeo.com"
"votes" => 22
]
0 => array:2 [▼
"url" => "Overstock.com"
"votes" => 15
]
4 => array:2 [▼
"url" => "Sears.com"
"votes" => 10
]
3 => array:2 [▼
"url" => "Glassdoor.com"
"votes" => 5
]
1 => array:2 [▼
"url" => "Fidelity.com"
"votes" => 5
]
6 => array:2 [▼
"url" => "Cbs.com"
"votes" => 1
]
]
}
*/
44. splice()
splice() is powered by the PHP array_splice() function as seen here. This allows you to
remove an item or items from the collection and replace with something else.
public function splice($offset, $length = null, $replacement = [])
{
if (func_num_args() == 1) {
return new static(array_splice($this->items, $offset));
}
We can test this out as we remove two items beginning at index 3 and replacing the hole
left with two new urls.
$collection = collect([
['url' => 'Spotify.com'],
['url' => 'Feedly.com'],
['url' => 'Lifehacker.com'],
['url' => 'Bloomberg.com'],
['url' => 'Foodnetwork.com'],
['url' => 'T-mobile.com'],
]);
var_dump($chunk);
dd($collection);
/*
object(Illuminate\Support\Collection)[111]
protected 'items' =>
array (size=2)
0 =>
array (size=1)
'url' => string 'Bloomberg.com' (length=13)
1 =>
array (size=1)
'url' => string 'Foodnetwork.com' (length=15)
Collection {#110 ▼
#items: array:6 [▼
0 => array:1 [▼
"url" => "Spotify.com"
]
1 => array:1 [▼
"url" => "Feedly.com"
]
2 => array:1 [▼
"url" => "Lifehacker.com"
]
3 => array:1 [▼
"url" => "Gizmodo.com"
]
4 => array:1 [▼
"url" => "Woot.com"
]
5 => array:1 [▼
"url" => "T-mobile.com"
]
]
}
*/
45. sum()
A quick and easy summing method you can use like so.
$collection = collect([2, 2])->sum();
dd($collection);
// 4
When you have nested arrays or objects, just pass the key you want to sum by.
$collection = collect([
['burger', 'cost' => 2.58],
['fries', 'cost' => 1.33],
['lemonade', 'cost' => 2.25],
['ice cream', 'cost' => 1.50]
])->sum('cost');
dd($collection);
// 7.66
46. take()
When you have a huge collection on your hands and only need a limited amount of items,
take() is your friend. Got 100 items and only need 5? take(5). Maybe you need to lose a
pound or two. Take only the first two from our prior example.
$collection = collect([
['burger', 'cost' => 2.58],
['fries', 'cost' => 1.33],
['lemonade', 'cost' => 2.25],
['ice cream', 'cost' => 1.50]
])->take(2);
dd($collection);
/*
Collection {#111 ▼
#items: array:2 [▼
0 => array:2 [▼
0 => "burger"
"cost" => 2.58
]
1 => array:2 [▼
0 => "fries"
"cost" => 1.33
]
]
}
*/
47. toArray()
Sometimes you might get stuck working with a collection problem that you can’t figure out.
When you need to drop down to a plain old PHP array, you can use toArray() to do so.
$collection = collect([
['url' => 'google.com'],
['url' => 'facebook.com'],
['url' => 'amazon.com'],
['url' => 'youtube.com'],
['url' => 'twitter.com'],
['url' => 'craigslist.com'],
['url' => 'reddit.com'],
['url' => 'pinterest.com'],
['url' => 'apple.com'],
['url' => 'instagram.com'],
['url' => 'wordpress.com'],
['url' => 'target.com'],
['url' => 'buzzfeed.com'],
['url' => 'microsoft.com'],
]);
dd($collection->toArray());
/*
array:14 [▼
0 => array:1 [▼
"url" => "google.com"
]
1 => array:1 [▼
"url" => "facebook.com"
]
2 => array:1 [▼
"url" => "amazon.com"
]
3 => array:1 [▼
"url" => "youtube.com"
]
4 => array:1 [▼
"url" => "twitter.com"
]
5 => array:1 [▼
"url" => "craigslist.com"
]
6 => array:1 [▼
"url" => "reddit.com"
]
7 => array:1 [▼
"url" => "pinterest.com"
]
8 => array:1 [▼
"url" => "apple.com"
]
9 => array:1 [▼
"url" => "instagram.com"
]
10 => array:1 [▼
"url" => "wordpress.com"
]
11 => array:1 [▼
"url" => "target.com"
]
12 => array:1 [▼
"url" => "buzzfeed.com"
]
13 => array:1 [▼
"url" => "microsoft.com"
]
]
*/
48. toJson()
You may also convert to JSON easy as pie.
$collection = collect([
['url' => 'google.com'],
['url' => 'facebook.com'],
['url' => 'amazon.com'],
['url' => 'youtube.com'],
['url' => 'twitter.com'],
['url' => 'craigslist.com'],
['url' => 'reddit.com'],
['url' => 'pinterest.com'],
['url' => 'apple.com'],
['url' => 'instagram.com'],
['url' => 'wordpress.com'],
['url' => 'target.com'],
['url' => 'buzzfeed.com'],
['url' => 'microsoft.com'],
]);
dd($collection->toJson());
/*
"[{"url":"google.com"},{"url":"facebook.com"},{"url":"amazon.com"},{"url":"youtube.com"},{"url":"twit
ter.com"},{"url":"craigslist.com"},{"url":"reddit.com"},{"url":"pinterest.com"},{"url":"apple.com"},{
"url":"instagram.com"},{"url":"wordpress.com"},{"url":"target.com"},{"url":"buzzfeed.com"},{"url":"mi
crosoft.com"}]"
*/
49. transform()
With transform() you can modify the collection directly by iterating over it with a callback.
$collection = collect([5, 10, 4, 15, 20]);
dd($collection->all());
/*
array:5 [▼
0 => 15
1 => 30
2 => 12
3 => 45
4 => 60
]
*/
50. unique()
unique() is another method I rather enjoy. It will return only the unique values in the
collection using this code here.
public function unique($key = null)
{
if (is_null($key)) {
return new static(array_unique($this->items, SORT_REGULAR));
}
$key = $this->valueRetriever($key);
$exists = [];
$exists[] = $id;
});
}
$unique = $collection->unique();
dd($unique);
/*
Collection {#111 ▼
#items: array:4 [▼
0 => "pizza"
2 => "water"
3 => "fruit juice"
5 => 7
]
}
*/
51. values()
This is a cool little method that returns the collection with the keys set to incrementing
numbers.
First without values()
$collection = collect([
'123' => 'google.com',
'234' => 'amazon.com',
'345' => 'yahoo.com',
'456' => 'ebay.com',
'567' => 'twitter.com',
'678' => 'craigslist.com',
'789' => 'netflix.com',
]);
dd($collection);
/*
Collection {#110 ▼
#items: array:7 [▼
123 => "google.com"
234 => "amazon.com"
345 => "yahoo.com"
456 => "ebay.com"
567 => "twitter.com"
678 => "craigslist.com"
789 => "netflix.com"
]
}
*/
dd($collection);
/*
Collection {#111 ▼
#items: array:7 [▼
0 => "google.com"
1 => "amazon.com"
2 => "yahoo.com"
3 => "ebay.com"
4 => "twitter.com"
5 => "craigslist.com"
6 => "netflix.com"
]
}
*/
52. where()
This is nice method you can use for finding a key value pair in your collection. Note this is
not the same as the database related where() as it can to employ operators such as
greater than, less than, like, etc. Let’s test it out.
$collection = collect([
['car' => 'Honda', 'mileage' => 2000],
['car' => 'Tesla', 'mileage' => 35000],
['car' => 'Subaru', 'mileage' => 15000],
['car' => 'Ford', 'mileage' => 100000],
['car' => 'Chevy', 'mileage' => 85000],
['car' => 'Kia', 'mileage' => 100250],
])->where('mileage', 15000);
dd($collection);
/*
Collection {#112 ▼
#items: array:1 [▼
2 => array:2 [▼
"car" => "Subaru"
"mileage" => 15000
]
]
}
*/
53. zip()
Finally we have the zip() method which combines values of a provided array with the
values of your collection where index positions are equal. Let’s add a warranty to all the
cars from our prior example as a test.
$collection = collect([
['car' => 'Honda', 'mileage' => 2000],
['car' => 'Tesla', 'mileage' => 35000],
['car' => 'Subaru', 'mileage' => 15000],
['car' => 'Ford', 'mileage' => 100000],
['car' => 'Chevy', 'mileage' => 85000],
['car' => 'Kia', 'mileage' => 100250],
])->zip([
'warranty',
'warranty',
'warranty',
'warranty',
'warranty',
'warranty',
]);
dd($collection);
/*
Collection {#112 ▼
#items: array:6 [▼
0 => Collection {#113 ▼
#items: array:2 [▼
0 => array:2 [▼
"car" => "Honda"
"mileage" => 2000
]
1 => "warranty"
]
}
1 => Collection {#114 ▼
#items: array:2 [▼
0 => array:2 [▼
"car" => "Tesla"
"mileage" => 35000
]
1 => "warranty"
]
}
2 => Collection {#115 ▼
#items: array:2 [▼
0 => array:2 [▼
"car" => "Subaru"
"mileage" => 15000
]
1 => "warranty"
]
}
3 => Collection {#116 ▼
#items: array:2 [▼
0 => array:2 [▼
"car" => "Ford"
"mileage" => 100000
]
1 => "warranty"
]
}
4 => Collection {#117 ▼
#items: array:2 [▼
0 => array:2 [▼
"car" => "Chevy"
"mileage" => 85000
]
1 => "warranty"
]
}
5 => Collection {#118 ▼
#items: array:2 [▼
0 => array:2 [▼
"car" => "Kia"
"mileage" => 100250
]
1 => "warranty"
]
}
]
}
*/
var_dump($carbon);
We can see here that it is an object of the Carbon\Carbon class. The next thing we see is
that there is a public property called date which is a string containing the date and the
time. timezone_type is the next public property we see which is an integer with a value of
3, and a public property named timezone which is a string having the value of UTC. We’ll
focus on that date property to start.
var_dump($carbon);
What we find when inspecting this instance with var_dump() is that we have the same type
of object as when we took the approach of using the new keyword to create a new
instance of the Carbon class. One might say this approach is slightly more readable, but it
doesn’t really matter which you choose.
Carbon::today()
Carbon::today() is another method you can use and is just slightly different than
Cabon::now(). You can use this when you’re not so much concerned at this exact moment
in time, but rather simply what day it is. As such, this method only gives you the string
representation of today and omits the time. We can see this by inspecting the var_dump
and noticing that the time is all zeroes.
$carbon = Carbon::today();
var_dump($carbon);
Carbon::tomorrow()
Carbon::tomorrow() is a useful method to dynamically determine the date of tomorrow. In
our prior example, we saw the date as 11/11 of 2015. If this method works correctly, we
should find a value of 11/12 of 2015 in our output.
$carbon = Carbon::tomorrow();
var_dump($carbon);
Excellent. Notice that the date did increment by one and we see the result of 11/12 of 2015.
Carbon::yesterday()
If we can easily return the value for tomorrow, it stands we should also be able to get the
value of yesterday. Alas, this is quite easy with Carbon.
$carbon = Carbon::yesterday();
var_dump($carbon);
This code is working just like we would expect it would, as it returns the value of 11/10 of
2015, which is a fine day indeed.
Carbon::create()
This method would be used to create an exact date and time of your choosing. This
method depends on you passing in some arguments. We can view the source of the
Carbon class to see what it expects.
public static function create($year = null, $month = null, $day = null, $hour = null, $minute =
null, $second = null, $tz = null)
{
$year = $year === null ? date('Y') : $year;
$month = $month === null ? date('n') : $month;
$day = $day === null ? date('j') : $day;
if ($hour === null) {
$hour = date('G');
$minute = $minute === null ? date('i') : $minute;
$second = $second === null ? date('s') : $second;
} else {
$minute = $minute === null ? 0 : $minute;
$second = $second === null ? 0 : $second;
}
When using Carbon::create(), you would typically pass in the parameters of year, month,
day, hour, minute, second, and timezone. We’ll test it out now.
$carbon = Carbon::create(1999, 12, 31, 23, 59, 59);
var_dump($carbon);
This of course represents New Years Eve which was a Friday on December 31st of 1999
with exactly one second left until “Yeah, they say two thousand zero zero party over, Oops
out of time, So tonight I’m gonna party like it’s 1999, Yeah.” You get the idea.
Carbon::createFromDate()
Maybe you need to create an object just based on the date, but not the time. This method
is just what you need for that.
$carbon = Carbon::createFromDate(1999, 12, 31);
var_dump($carbon);
This gives us the same date, however the time is simply filled in with the current time
rather than a specific time you provide as parameters to the method.
Carbon::createFromTime()
This method allows you to set a specific time of the current day.
$carbon = Carbon::createFromTime(13, 35, 55);
var_dump($carbon);
Notice that the time is reflected as the values we passed in, while the date is an instance
of today.
Carbon::createFromTimestamp
If you have a timestamp you would like to create a Carbon instance from, we can use this
method.
$carbon = Carbon::createFromTimestamp(1447271429);
var_dump($carbon);
var_dump($carbon);
var_dump($carbon);
var_dump($carbon);
var_dump($carbon);
var_dump($carbon);
var_dump($carbon);
All of these are interpreted correctly by Carbon and PHP and provide the output like so.
We can also pass in a string which represents something like 3 days ago or 4 days from
now. In addition to this, you can specify plus or minus hours as well to get more granular.
Here are a few examples.
$carbon = new Carbon('-3 days');
// object(Carbon\Carbon)[141]
// public 'date' => string '2015-11-08 21:31:13.000000' (length=26)
// public 'timezone_type' => int 3
// public 'timezone' => string 'UTC' (length=3)
// object(Carbon\Carbon)[142]
// public 'date' => string '2015-10-14 21:33:08.000000' (length=26)
// public 'timezone_type' => int 3
// public 'timezone' => string 'UTC' (length=3)
// object(Carbon\Carbon)[141]
// public 'date' => string '2010-11-11 21:33:51.000000' (length=26)
// public 'timezone_type' => int 3
// public 'timezone' => string 'UTC' (length=3)
// object(Carbon\Carbon)[142]
// public 'date' => string '2015-11-14 06:35:06.000000' (length=26)
// public 'timezone_type' => int 3
// public 'timezone' => string 'UTC' (length=3)
// object(Carbon\Carbon)[141]
// public 'date' => string '2015-12-06 21:36:39.000000' (length=26)
// public 'timezone_type' => int 3
// public 'timezone' => string 'UTC' (length=3)
// object(Carbon\Carbon)[142]
// public 'date' => string '2018-12-13 03:12:44.000000' (length=26)
// public 'timezone_type' => int 3
// public 'timezone' => string 'UTC' (length=3)
This is pretty cool and we have covered most ways you would ever be creating an instance
of Carbon manually. Now we can take a look at formatting dates with Carbon which is
where Carbon really shines.
$formatted = $carbon->toDateString();
var_dump($formatted);
toTimeString()
The toTimeString() method formats the time in the Carbon object to a properly formatted
time string.
$carbon = new Carbon('-2 days 10 hours');
$formatted = $carbon->toTimeString();
var_dump($formatted);
// string '08:26:32' (length=8)
What happened in this example is that since we did not actually provide a time in the
constructor, the current time is used at the time of the code executing. We did however
have a subtraction clause, and we were removing 10 hours, so that does get reflected in
the time string.
toDateTimeString()
$carbon = new Carbon('+5 days');
$formatted = $carbon->toDateTimeString();
var_dump($formatted);
toAtomString()
You may format the the date and time as an atom string like so.
$carbon = new Carbon('tomorrow');
$formatted = $carbon->toAtomString();
var_dump($formatted);
toCookieString()
Formatting the date and time to the standard of a cookie is easy with the toCookieString()
method.
$carbon = new Carbon('next week');
$formatted = $carbon->toCookieString();
var_dump($formatted);
toDayDateTimeString()
This is how the toDayDateTimeString() method works, and the output is very nice.
$carbon = new Carbon('now');
$formatted = $carbon->toDayDateTimeString();
var_dump($formatted);
toFormattedDateString()
The toFormattedDateString() outputs your Carbon instance like so.
$carbon = new Carbon('now');
$formatted = $carbon->toFormattedDateString();
var_dump($formatted);
toIso8601String()
There are several standards based date and time formats. This one is for ISO 8601.
$carbon = new Carbon('now');
$formatted = $carbon->toIso8601String();
var_dump($formatted);
toRfc822String()
We have built in support for RFC 822 via the toRfc822String() method.
$carbon = new Carbon('now');
$formatted = $carbon->toRfc822String();
var_dump($formatted);
toRfc850String()
Get your RFC 850 formatted strings out of your Carbon object with the toRfc850String()
method.
$carbon = new Carbon('now');
$formatted = $carbon->toRfc850String();
var_dump($formatted);
// string 'Wednesday, 11-Nov-15 22:53:09 UTC' (length=33)
toRfc1036String()
Formatting RFC 1036 date time is a breeze with the toRfc1036String() method.
$carbon = new Carbon('now');
$formatted = $carbon->toRfc1036String();
var_dump($formatted);
toRfc1123String()
This is how you can set the format to an RFC 1123 string.
$carbon = new Carbon('now');
$formatted = $carbon->toRfc1123String();
var_dump($formatted);
toRfc2822String()
Are you in need of an RFC 2822 formatted string? You are in luck with the
toRfc2822String() method.
$carbon = new Carbon('now');
$formatted = $carbon->toRfc2822String();
var_dump($formatted);
toRfc3339String()
Maybe RFC 3339 is what you are looking for. The toRfc3339String() method is the one
you need.
$carbon = new Carbon('now');
$formatted = $carbon->toRfc3339String();
var_dump($formatted);
$formatted = $carbon->toRssString();
var_dump($formatted);
toTimeString()
The toTimeString() method offers a way to output a very simple format like so.
$carbon = new Carbon('now');
$formatted = $carbon->toTimeString();
var_dump($formatted);
toW3cString()
Easily format to the W3C string format with the toW3cString() method.
$carbon = new Carbon('now');
$formatted = $carbon->toW3cString();
var_dump($formatted);
All of these methods begin with to as we can see here. There is a bit of overlap between
the names of the methods and the formats they provide, but what this does is allow you to
structure your code in a way that makes the most sense possible to you. In other words,
you have enough sugar to make things easier to reason about during development.
Now you might be thinking about the standard way we format dates in PHP when using
things like strtotime(), DateTime and date_create() in native PHP. The same rules apply for
Carbon, and if you prefer, you can simply use the format() method like so.
$carbon = new Carbon('now');
$formatted = $carbon->format('l');
var_dump($formatted);
// string 'Thursday' (length=8)
//--------------------------------------------------------//
var_dump($formatted);
// string 'Thursday 12th of November 2015 01:33:57 AM' (length=42)
//--------------------------------------------------------//
$formatted = $carbon->format(DATE_RFC2822);
var_dump($formatted);
// string 'Thu, 12 Nov 2015 01:33:57 +0000' (length=31)
//--------------------------------------------------------//
$formatted = $carbon->format(DATE_ATOM);
var_dump($formatted);
// string '2015-11-12T01:33:57+00:00' (length=25)
//--------------------------------------------------------//
var_dump($formatted);
// string 'Thursday the 12th' (length=17)
//--------------------------------------------------------//
var_dump($formatted);
// string 'November 12, 2015, 1:33 am' (length=26)
//--------------------------------------------------------//
$formatted = $carbon->format('"m.d.y');
var_dump($formatted);
// string '"11.12.15' (length=9)
//--------------------------------------------------------//
var_dump($formatted);
// string '12, 11, 2015' (length=12)
//--------------------------------------------------------//
$formatted = $carbon->format('Ymd');
var_dump($formatted);
// string '20151112' (length=8)
//--------------------------------------------------------//
var_dump($formatted);
// string 'it is the 12th day.' (length=19)
//--------------------------------------------------------//
var_dump($formatted);
// string 'Thu Nov 12 1:33:57 UTC 2015' (length=27)
//--------------------------------------------------------//
var_dump($formatted);
// string '01:11:57 m is month' (length=19)
//--------------------------------------------------------//
$formatted = $carbon->format('H:i:s');
var_dump($formatted);
// string '01:33:57' (length=8)
//--------------------------------------------------------//
var_dump($formatted);
// string '2015-11-12 01:33:57' (length=19)
Behold diffForHumans() !
This is one of the coolest methods in the Carbon Library. What it does is to compare the
current date and time to that which is stored in the current instance of Carbon. For
example, the Carbon instance itself may hold a timestamp or some format of date and time
from a few days ago, or perhaps even something in the future. The diffForHumans()
method creates really nicely formatted and human readable formats from this difference in
time. Let’s see a few examples.
$carbon = new Carbon('-5 days');
$formatted = $carbon->diffForHumans();
var_dump($formatted);
// string '5 days ago' (length=10)
//--------------------------------------------------------//
$formatted = $carbon->diffForHumans();
var_dump($formatted);
// string '2 hours from now' (length=16)
//--------------------------------------------------------//
var_dump($formatted);
// string '33 minutes ago' (length=14)
//--------------------------------------------------------//
$formatted = $carbon->diffForHumans();
var_dump($formatted);
// string '55 seconds ago' (length=14)
Carbon Getters
We already had a look at all of the ways we can format dates and times with Carbon. Now
what happens if you want to access say just the day, or just the hour, or just the minute
you are interested in? Do you re format the Carbon instance and then retrieve the values
as you want? No you don’t have to do that, you can make use of the special getter
methods which will retrieve dates and times in the format you like. Let’s take a look at the
source code that makes this possible, since it will enlighten us on how Carbon is actually
working it’s magic.
Getter Functionality
public function __get($name)
{
switch (true) {
case array_key_exists($name, $formats = array(
'year' => 'Y',
'yearIso' => 'o',
'month' => 'n',
'day' => 'j',
'hour' => 'G',
'minute' => 'i',
'second' => 's',
'micro' => 'u',
'dayOfWeek' => 'w',
'dayOfYear' => 'z',
'weekOfYear' => 'W',
'daysInMonth' => 't',
'timestamp' => 'U',
)):
return (int) $this->format($formats[$name]);
default:
throw new InvalidArgumentException(sprintf("Unknown getter '%s'", $name));
}
}
This code now makes it extremely easy and convenient to do things like we see here
giving us quick access to the integer values of all of the various parts of a date time.
$carbon = new Carbon('now');
$carbon->year; // 2015
$carbon->yearIso; // 2015
$carbon->month; // 11
$carbon->day; // 12
$carbon->hour; // 16
$carbon->minute; // 5
$carbon->second; // 1
$carbon->micro; // 0
$carbon->dayOfWeek; // 4
$carbon->dayOfYear; // 315
$carbon->weekOfYear; // 46
$carbon->daysInMonth; // 30
$carbon->timestamp; // 1447344301
Carbon Setters
Just as we have getters we can work with in Carbon to make things easier for us, Carbon
also provides a nice Setter functionality. Using setters in Carbon is like another way to
create an instance of a date time in Carbon. Sometimes it is easier to explicitly set the year
month day or hour manually, rather than to figure out how to properly pass in the right
format to do so. Let’s have a look at the Carbon source code which makes these setters
possible. We can see that it has support for setting the year, month, day, hour, minute,
second, timestamp, and timezone. If you pass in something the code does not understand,
it will throw an exception.
Setter Functionality
public function __set($name, $value)
{
switch ($name) {
case 'year':
$this->setDate($value, $this->month, $this->day);
break;
case 'month':
$this->setDate($this->year, $value, $this->day);
break;
case 'day':
$this->setDate($this->year, $this->month, $value);
break;
case 'hour':
$this->setTime($value, $this->minute, $this->second);
break;
case 'minute':
$this->setTime($this->hour, $value, $this->second);
break;
case 'second':
$this->setTime($this->hour, $this->minute, $value);
break;
case 'timestamp':
parent::setTimestamp($value);
break;
case 'timezone':
case 'tz':
$this->setTimezone($value);
break;
default:
throw new InvalidArgumentException(sprintf("Unknown setter '%s'", $name));
}
}
Now consider we new up a Carbon instance like so.
$carbon = new Carbon('now');
var_dump($carbon);
What happens however when we go ahead and set some of the values in that Carbon
instance? Let’s find out! We will new up the instance, set some properties, then var dump it
and also output the result as a formatted string.
$carbon = new Carbon('now');
$carbon->year = 2012;
$carbon->month = 3;
$carbon->day = 5;
var_dump($carbon);
echo $carbon->toDayDateTimeString();
So we see that we can easily set values on our Carbon instance and update it with ease.
Carbon Timezone
Carbon makes working with Timezones in PHP really easy. You can interact with
timezones in Carbon via the property $timezone and it’s alias $tz. You will need to make
sure however, that you are using one of the supported timezones in PHP. For example,
here is the list of supported timezones in America. With this knowledge, let us set up a new
Carbon instance with the Time Zone of New York City.
$carbon = Carbon::now('America/New_York');
var_dump($carbon);
Another way you might tackle implementing a Time Zone in Carbon is like so.
$carbon = Carbon::createFromDate(2010, 5, 14, 'America/Chicago');
var_dump($carbon);
// object(Carbon\Carbon)[141]
// public 'date' => string '2010-05-14 18:35:38.000000' (length=26)
// public 'timezone_type' => int 3
// public 'timezone' => string 'America/Chicago' (length=15)
If you would rather use a method instead of passing in an argument, you can also
complete setting the time zone this way as well. Here are a few more ways we might to
this.
$carbon = Carbon::now();
$carbon->tz('America/Denver');
var_dump($carbon);
// object(Carbon\Carbon)[141]
// public 'date' => string '2015-11-12 11:39:03.000000' (length=26)
// public 'timezone_type' => int 3
// public 'timezone' => string 'America/Denver' (length=14)
$carbon = Carbon::now();
$carbon->setTimezone('America/Phoenix');
var_dump($carbon);
// object(Carbon\Carbon)[141]
// public 'date' => string '2015-11-12 11:40:49.000000' (length=26)
// public 'timezone_type' => int 3
// public 'timezone' => string 'America/Phoenix' (length=15)
$carbon = Carbon::now();
$carbon->tz = 'America/Los_Angeles';
var_dump($carbon);
// object(Carbon\Carbon)[141]
// public 'date' => string '2015-11-12 10:41:57.000000' (length=26)
// public 'timezone_type' => int 3
// public 'timezone' => string 'America/Los_Angeles' (length=19)
So we can see that Carbon is quite flexible, and you have several ways to accomplish the
same task.
var_dump($carbon);
// object(Carbon\Carbon)[142]
// public 'date' => string '2015-10-30 18:47:21.000000' (length=26)
// public 'timezone_type' => int 3
// public 'timezone' => string 'UTC' (length=3)
$carbon->addDays(1);
var_dump($carbon);
// object(Carbon\Carbon)[142]
// public 'date' => string '2015-10-31 18:49:01.000000' (length=26)
// public 'timezone_type' => int 3
// public 'timezone' => string 'UTC' (length=3)
$carbon->addDays(10);
var_dump($carbon);
// object(Carbon\Carbon)[142]
// public 'date' => string '2015-11-10 18:51:25.000000' (length=26)
// public 'timezone_type' => int 3
// public 'timezone' => string 'UTC' (length=3)
Subtract Days Using Carbon
Just as we can easily add a given number of days to a Carbon object, we can just as
easily subtract days.
$carbon = Carbon::createFromDate(2015, 10, 30);
var_dump($carbon);
// object(Carbon\Carbon)[142]
// public 'date' => string '2015-10-30 18:54:22.000000' (length=26)
// public 'timezone_type' => int 3
// public 'timezone' => string 'UTC' (length=3)
$carbon->subDays(1);
var_dump($carbon);
// object(Carbon\Carbon)[142]
// public 'date' => string '2015-10-29 18:54:22.000000' (length=26)
// public 'timezone_type' => int 3
// public 'timezone' => string 'UTC' (length=3)
$carbon->subDays(10);
var_dump($carbon);
// object(Carbon\Carbon)[142]
// public 'date' => string '2015-10-19 18:54:22.000000' (length=26)
// public 'timezone_type' => int 3
// public 'timezone' => string 'UTC' (length=3)
This is really so slick. We can see that Carbon takes care of everything for us. If we
happen to add so many days that it is going to go into the next month, Carbon is smart
enough to adjust the month as well. There are a ton more methods you can use such as
add(), addDay(), addDays(), addHour(), addHours(), addMinute(), addMinutes(),
addMonth(), addMonthNoOverflow(), addMonths(), addMonthsNoOverflow(), addSecond(),
addSeconds(), addWeek(), addWeekday(), addWeekdays(), addWeeks(), addYear(),
addYears(), sub(), subDay(), subDays(), subHour(), subHours(), subMinute(),
subMinutes(), subMonth(), subMonthNoOverflow(), subMonths(), subMonthsNoOverflow(),
subSecond(), subSeconds(), subWeek(), subWeekday(), subWeekdays(), subWeeks(),
subYear(), and subYears(). That’s a lot of methods to work with! Your best bet would be to
test them out for yourself, and see what works best for your particular application.
if ($carbonone->eq($carbontwo)) {
echo 'The two dates are equal!';
} else {
echo 'These two dates are not equal!';
}
if ($carbontwo->gt($carbonone)) {
echo 'Carbon 2 is greater than Carbon 1!';
} else {
echo 'Carbon 2 is *not* greater than Carbon 1!';
}
if ($carbonone->lt($carbontwo)) {
echo 'Carbon 1 is less than Carbon 2!';
} else {
echo 'Carbon 1 is *not* less than Carbon 2!';
}
We can see how the gt(), lt(), and eq() methods work which allow us to quickly check for
equality between two dates. In addition you can use the gte() and lte() methods if you need
to check for a greater than or equal to, and less than or equal to situation.
Checking Between Dates With Carbon
We have a nice between() method for checking where a date exists between two given
dates. Let’s see how this works.
$carbonone = new Carbon;
$carbontwo = new Carbon('+5 days');
$carbonthree = new Carbon('+1 year');
if($carbonone->between($carbontwo, $carbonthree)){
echo 'Carbon 1 is between Carbon 2 and Carbon 3!';
} else {
echo 'Carbon 1 is *not* between Carbon 2 and Carbon 3!';
}
if($carbontwo->between($carbonone, $carbonthree)){
echo 'Carbon 2 is between Carbon 1 and Carbon 3!';
} else {
echo 'Carbon 2 is *not* between Carbon 1 and Carbon 3!';
}
echo 'The Honda was built '.$honda->diffInYears($subaru).' years before the Subaru';
Now just like everything else in Carbon, you have many more methods available to you.
echo $carbon->endOfWeek()->toDayDateTimeString();
// Sun, Nov 15, 2015 11:59 PM
$carbon = Carbon::now();
echo $carbon->startOfMonth()->toDayDateTimeString();
// Sun, Nov 1, 2015 12:00 AM
$carbon = Carbon::now();
echo $carbon->startOfYear()->toDayDateTimeString();
// Thu, Jan 1, 2015 12:00 AM
Carbon Next
The next() method is a really useful one in Carbon. How often do you talk to other people
using the next nomenclature? You’ll be like, “Hey Tom, I’ll see you next week!” or “Jill, I
don’t have a free night until next Wednesday” and so on and so forth. The next() method in
Carbon accepts a dayOfWeek integer value, however it is null by default. Recall that in
PHP 0 is Sunday, and 6 is Saturday. Let’s try it out.
$carbon = Carbon::now();
echo 'Hey Julie, see you next '. $carbon->next(3)->format('l \t\h\e jS');
If we omit the argument to the next() method, it will just move forward one week starting
from today. Today is Thursday as we write this, so this is what the output is when we
combine with our handy toCookieString() formatting method.
$carbon = Carbon::now();
echo $carbon->next()->toCookieString();
// Thursday, 19-Nov-2015 00:00:00 UTC
Carbon Previous
The complimentary method to next() is of course previous(). Let’s try it.
$carbon = Carbon::now();
echo $carbon->previous()->toCookieString();
// Thursday, 05-Nov-2015 00:00:00 UTC
Carbon Copy
The copy() method is very important in Carbon. The reason is, if you call modifying
methods on an instance of Carbon, that instance gets immediately updated directly. It is
not a copy of the object, but a reference. Let’s see an example.
$carbon = new Carbon('Thursday November 12th');
$carbon->addDay();
echo $carbon->format('l');
// Friday
This works as expected. We create a Carbon instance based on a Thursday, add a day,
and see that the output is now Friday. Check this out however.
$carbonone = new Carbon('Thursday November 12th');
$carbontwo = $carbonone->addDay();
if ($carbonone->eq($carbontwo)) {
echo 'these days are equal';
} else {
echo 'these days are *not* equal';
}
This is saying that $carbonone and $carbontwo are equal, is that right? It looks like
$carbonone should be a Thursday and $carbontwo should be a Friday, why is this saying
the days are equal? Let’s add in the copy() method to get something more consistent.
$carbonone = new Carbon('Thursday November 12th');
$carbontwo = $carbonone->copy()->addDay();
if ($carbonone->eq($carbontwo)) {
echo 'these days are equal';
} else {
echo 'these days are *not* equal';
}
$tomorrow = $today->addDay();
// Today is Thursday
// Today is Friday and Tomorrow is Friday
$tomorrow = $today->copy()->addDay();
// Today is Thursday
// Today is Thursday and Tomorrow is Friday
We can see use of the today() method (instantiation) and lt() method (comparison).
Checking for a Grace Period
/**
* Determine if the entity is on grace period after cancellation.
*
* @return bool
*/
public function onGracePeriod()
{
if (! is_null($endsAt = $this->getSubscriptionEndDate())) {
return Carbon::now()->lt(Carbon::instance($endsAt));
} else {
return false;
}
}
We can see use of the now() method (instantiation) and lt() method (comparison), as well
as the instance() method (instantiation).
Creating a Carbon Instance from a Timestamp
/**
* Get a Carbon date for the invoice.
*
* @param \DateTimeZone|string $timezone
* @return \Carbon\Carbon
*/
public function date($timezone = null)
{
$carbon = Carbon::createFromTimestamp($this->date);
Here we can see the code making use of the createFromTimestamp() method
and setTimeZone() method which is fluent.
Calculating Remaining Trial Days
/**
* Calculate the remaining trial days based on the current trial end.
*
* @param \Carbon\Carbon $trialEnd
* @return void
*/
protected function calculateRemainingTrialDays($trialEnd)
{
// If there is still trial left on the current plan, we'll maintain that amount of
// time on the new plan. If there is no time left on the trial we will force it
// to skip any trials on this new plan, as this is the most expected actions.
$diff = Carbon::now()->diffInHours($trialEnd);
This gives us a good idea of how Carbon might be used in the real world with real code
powering real transactions. Read through the source further on your own if you are
interested!
• Create a blog directory within the public directory of your Laravel Install
• Place all the WordPress Files in the blog directory
• Create a new database on your server to support the new WordPress install
• Update your nginx configuration to support WordPress and Laravel Simultaneously
• Restart the nginx service
• Install WordPress
notes:Again, we make a few assumptions for this tutorial. One being that you have your
own VPS, and two being that it is a LEMP stack. LEMP is Linux, Nginx, MySQL, and PHP.
Your own VPS gives you the ability to create an additional database easily. It’s a good idea
to keep the database from your main application and the WordPress database separate. If
you we’re looking to combine the two, there are ways to do that, but not in this tutorial.
The index.php file in the public directory is the entry into your Laravel application. You will
load the WordPress files into the public/blog directory such that the index.php file for
WordPress exists in blog. This is the entry into your WordPress blog.
3. Create a database for the WordPress install
If you have a GUI tool such as phpmyadmin installed, this will be a cinch. If not, you can
still ssh into your VPS and create the new database from the command line without too
much trouble. For our example, we used the name wordpress as the new database name.
listen 80;
server_name laravelapp.io;
root /home/vagrant/Code/laravel;
charset utf-8;
location / {
access_log off;
sendfile off;
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_intercept_errors off;
fastcgi_buffer_size 16k;
fastcgi_buffers 4 16k;
}
location ~ /\.ht {
deny all;
location ^/blog/index.php(/.*)?$ {
fastcgi_split_path_info ^(/blog/index.php)(/.+)$;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
fastcgi_read_timeout 1000;
include fastcgi_params;
location /blog/ {
if (!-e $request_filename) {
Once you have updated the nginx configuration file, found in /etc/nginx/sites-available,
be sure to restart the nginx service via sudo service nginx restart.
5. Configure wp-config.php
Set up your database configuration for the blog by renaming wp-config-sample.php to wp-
config.phpand fill in the credentials to connect to the new database you created in step 3.
A snippet of that configuration file might look a bit like this.
// ** MySQL settings - You can get this info from your web host ** //
/** The name of the database for WordPress */
define('DB_NAME', 'wordpress');
* * * * * * everyMinute()
*/5 * * * * * everyFiveMinutes()
*/10 * * * * * everyTenMinutes()
0,30 * * * * * everyThirtyMinutes()
0 * * * * * hourly()
0 0 * * * * daily()
0 0 * * 0 * weekly()
0 0 1 * * * monthly()
0 0 1 */3 * quarterly()
0 0 1 1 * * yearly()
You can do simple things like clean up your database, email reports, or you could
even earn $4 million dollars per year with a cron job. Use your imagination to see what you
could imagine applying a cron job to. As we can see from the table above, it is easier to
remember the textual based method names than it is to memorize the syntax of cron jobs
which is a bit cryptic. You can be more granular than the options listed here, but in most
cases, these options should be more than enough to cover whatever you might like to do
with a cron job.
In this snippet, we can see that the schedule() function accepts a type hinted instance of
the Scheduleclass. Then in the body of the schedule() function, we are able to define a
schedule to fire artisan commands. The command above is commented out by default
when Laravel is first installed. If we were to uncomment it, like we did above, it turns into
the equivalent of running php artisan inspire at the command line every hour.
linux terminal commands
In addition to running artisan commands, you can run terminal commands using exec().
Here we will list the contents of a directory and send that output to a text file.
protected function schedule(Schedule $schedule)
{
$schedule->exec('cd ~/Code/lpg && ls')
->everyMinute()
->sendOutputTo('/home/vagrant/Code/lpg/listing.txt');
}
If you wanted to test this out on your local server, such as homestead just to see how it
works, we can do this. Although setting up cron jobs on a virtual machine you destroy and
rebuild in a test environment will not accomplish a lot for you, it makes perfect sense for
you to actually test out how this works before you try screwing up configuring your
production server.
vagrant@homestead:~/Code/lpg$ crontab -e
You may get some output similar to what you see here.
# Edit this file to introduce tasks to be run by cron.
#
# Each task to run has to be defined through a single line
# indicating with different fields when the task will be run
# and what command to run for the task
#
# To define the time you can provide concrete values for
# minute (m), hour (h), day of month (dom), month (mon),
# and day of week (dow) or use '*' in these fields (for 'any').#
# Notice that tasks will be started based on the cron's system
# daemon's notion of time and timezones.
#
# Output of the crontab jobs (including errors) is sent through
# email to the user the crontab file belongs to (unless redirected).
#
# For example, you can run a backup of all your user accounts
# at 5 a.m every week with:
# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
#
# For more information see the manual pages of crontab(5) and cron(8)
#
# m h dom mon dow command
If you are prompted which text editor to use, we chose nano, so you can choose that
option too. Then all you need to do is paste that cron we mentioned earlier into the file and
save it. Now, you must first find the present working directory of where artisan lives for
your project, and this will be what you paste into the cron file. Our little test project lives in
a directory called lpg. So we ssh into our vagrant box, and then cd into Code/lpg. In here
we run pwd and we are provided with the path of /home/vagrant/Code/lpg. Do not forget to
append artisan to this path! Here is the original and updated cron job we will configure.
original
* * * * * php /path/to/artisan schedule:run >> /dev/null 2>&1
updated
* * * * * php /home/vagrant/Code/lpg/artisan schedule:run >> /dev/null 2>&1
Now, we run crontab - e again, and enter the above string as the last line of the file and
save.
Everything should be running at this point, and now we can test some actual commands
and see if they work. This first one will list out the contents of our laravel directory and
save them to a file called listing.txt.
protected function schedule(Schedule $schedule)
{
$schedule->exec('cd ~/Code/lpg && ls')
->everyMinute()
->sendOutputTo('/home/vagrant/Code/lpg/listing.txt');
}
In the above snippet, we are able to hook right into the server and run a command as if we
are at the terminal. First, we pass in the command we want to run as a string to exec().
Notice that we pass in cd ~/Code/lpg && ls. This says, we are going to change into the
lpg directory, and once we are there also run an ls command. The next method tells
Laravel to do this every minute. In addition to this, we want to send the output of this
command to a file. We need to provide the path to the location of where we want to store
the output of our command. We will pass in what amounts to the same exact directory, and
place the output into a file called listing.txt.
If we wait a couple of minutes just to make sure we give the cron a chance to run, we can
then check to see if our command worked. We navigate to our laravel directory in the
terminal, and run the command cat listing.txt. Lo and behold, it worked! We can see
the contents of our laravel directory are contained in the file we specified.
vagrant@homestead:~/Code/lpg$ cat listing.txt
app
artisan
bootstrap
composer.json
composer.lock
config
database
gulpfile.js
_ide_helper.php
listing.txt
package.json
phpunit.xml
public
readme.md
resources
server.php
storage
tests
vendor
So that is pretty cool, we got it running and that is the main thing. At this point you can try
all the different methods available to you to see how they work. Once you flesh them out
locally, you’ll feel more confident about putting things on a live server.
if (defined('HHVM_VERSION')) {
$binary .= ' --php';
}
if (defined('ARTISAN_BINARY')) {
$artisan = ProcessUtils::escapeArgument(ARTISAN_BINARY);
} else {
$artisan = 'artisan';
}
return $event;
}
In looking at the command that runs every minute, we can investigate what is happening.
In the ScheduleRunCommand.php class there is a fire() method which fetches the events
that are ready to be fired. We then loop over each one of them and run the event.
public function fire()
{
$events = $this->schedule->dueEvents($this->laravel);
$eventsRan = 0;
$event->run($this->laravel);
++$eventsRan;
}
We can see that the isDue() method in the Schedule class uses array_filter() to examine
the events array that has been populated, and returns only the ones that are due. There
might be 5 or 10 in the array, but only the ones that are due will be fired.
public function dueEvents($app)
{
return array_filter($this->events, function ($event) use ($app) {
return $event->isDue($app);
});
}
Laravel makes use of a third party package to actually inspect the events to determine if
they are due. We can see that in this code here.
public function isDue($app)
{
if (! $this->runsInMaintenanceMode() && $app->isDownForMaintenance()) {
return false;
}
/**
* Determine if the Cron expression passes.
*
* @return bool
*/
protected function expressionPasses()
{
$date = Carbon::now();
if ($this->timezone) {
$date->setTimezone($this->timezone);
}
return CronExpression::factory($this->expression)->isDue($date->toDateTimeString());
}
Scheduling Commands and Tasks In Laravel Summary
There is a bit more to it than what we have covered so far, but this is certainly enough to
be dangerous with the Scheduler. Ultimately the takeaway is that we can easily build up an
array to hold events to be fired. This works almost like a queue. Then, Laravel evaluates
that array and fires off events as they are due. The API is very user friendly, and you’ll be
amazed at how nice it is to use once you get used to it. Like all other tutorials, continue to
have a play with the various commands available to you until they become easy and
familiar to you.
Part of working with Laravel is not only creating the web based, or HTTP
focused functionality, but also leveraging Artisan. Artisan is the part of your
application that operates from the command line. If you’re used to strictly
graphical user interface based applications, Artisan will be a bit to understand
at first. With time however, you’ll begin to appreciate just how much you can
accomplish via very simple commands you type in at the console. You may
already be familiar with doing things like creating migrations, clearing the
cache, generating boilerplate code for controllers, events, jobs, middleware,
tests, and more. All of this is accomplished through Artisan. Now comes the fun
part, you can create your own custom commands as well which will be added to
the list of Artisan commands on your application. Let’s see how.
php artisan inspire
First, we’ll take a look at the inspiring quote generator that ships with Laravel. In order to
test it out, we had to uncomment a line in the protected $commands property of
the Kernel class. If you want to follow along, find your Kernel.php in app/Console and it
should look like this.
<?php
namespace App\Console;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
/**
* Define the application's command schedule.
*
* @param \Illuminate\Console\Scheduling\Schedule $schedule
* @return void
*/
protected function schedule(Schedule $schedule)
{
// Schedule taks here
}
}
With this, we have turned on the ability to use this command. In other words, it is now
registered. Let’s go ahead and take it for a test run.
vagrant@homestead:~/Code/lpg$ php artisan inspire
Very little is needed to make a happy life. – Marcus Antoninus
vagrant@homestead:~/Code/lpg$ php artisan inspire
Simplicity is the essence of happiness. – Cedric Bledsoe
vagrant@homestead:~/Code/lpg$ php artisan inspire
He who is contented is rich. – Laozi
So this is pretty neat. We turned on the ability to use this command, and took it for a test
run. We can see from the above output that we got some inspiring quotes. As a simple
exercise, let’s say you wanted to create your own quote generator and run it from the
command line. How would you do that? Well, it turns out it’s pretty easy – let’s give it a
shot.
namespace App\Console\Commands;
use Illuminate\Console\Command;
/**
* The console command description.
*
* @var string
*/
protected $description = 'Command description';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
//
}
}
You might be thinking, ok great – so what do I do with this? We’re going to start super
simple. The first thing you will do is to modify the signature property. This is what
determines what you see as the command when you run php artisan. Change that
signature to the following.
protected $signature = 'quote:generate';
Great! Now, let’s register, or turn on, this command. To do this, navigate to
app/Console/Kernel.php and add the entry for this newly generated class to
the $commands array like so.
<?php
namespace App\Console;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
use Carbon\Carbon;
/**
* Define the application's command schedule.
*
* @param \Illuminate\Console\Scheduling\Schedule $schedule
* @return void
*/
protected function schedule(Schedule $schedule)
{
// Schedule taks here
}
}
Our command is now registered and available to use. To see it in the menu, just run php
artisan list quote.
vagrant@homestead:~/Code/lpg$ php artisan list quote
Laravel Framework version 5.2.20
Usage:
command [options] [arguments]
Options:
-h, –help Display this help message
-q, –quiet Do not output any message
-V, –version Display this application version
–ansi Force ANSI output
–no-ansi Disable ANSI output
-n, –no-interaction Do not ask any interactive question
–env[=ENV] The environment the command should run under.
-v|vv|vvv, –verbose Increase the verbosity of messages: 1 for normal output, 2 for more
verbose
output and 3 for debug
Available commands for the “quote” namespace:
quote:generate Command description
Note:We can see from the output above that Laravel is indeed now aware of
a quote:generatecommand. Our command still has a generic description. Let’s change
that by giving a custom description to what our command will do. All we have to do is
update the $description property in our QuoteGenerator class to something like so.
protected $description = 'Generate a random quote.';
With this update, we can check it out on the console one more time.
vagrant@homestead:~/Code/lpg$ php artisan list quote
…
Available commands for the “quote” namespace:
quote:generate Generate a random quote.
Notice our new command description is now active.
Add logic to handle()
Right now, our newly created command does a whole lot of nothing. Let’s test it.
vagrant@homestead:~/Code/lpg$ php artisan quote:generate
vagrant@homestead:~/Code/lpg$
Nothing happened. We’re right back at the command line with no effect. The place to add
logic to your command is in the handle() method of your newly created class. If we
navigate to our app/Console/Commands/QuoteGenerator.php class, we find that it has a
public function named handle(). This is where the action happens. When your command
runs, any logic contained in this function will be processed. We wanted to create some
quotes, and randomly display them to the console. Let’s add some logic to do this. We will
take inspiration from iamdeveloper to power our quotes.
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
/**
* The console command description.
*
* @var string
*/
protected $description = 'Generate a random quote.';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
$quotes = [
'waiter, waiter lemme guess, there’s a fly in your soup? no i just wanted to say I use
Vim',
'project manager: i know enough coding to be dangerous *winks* literally ruins entire
codebase',
'The software development process i can’t fix this *crisis of confidence* *questions
career* *questions life* oh it was a typo, cool',
'Web dev in 2016: Keep installing Babel plugins until it works',
'my colleague is building a js app with no framework, no build tool, no compilers…like
some sort of psychopath',
'“Made with love” I call BS.',
'Never trust a developer wearing a suit.',
'We love your open source work, the code is excellent, but would you mind showing us a
quick fibonacci sequence on the whiteboard?',
'Give a man a fish and you feed him for a day, Teach a man to fish and you feed him for a
lifetime, Give a startup $$ and they’ll waste it.',
'“The Top 100 JavaScript Frameworks of 2015″ ಠ_ಠ this is an issue.',
];
shuffle($quotes);
$this->info($quotes[0]);
}
Check it out!
vagrant@homestead:~/Code/lpg$ php artisan quote:generate
The software development process i can’t fix this *crisis of confidence* *questions career*
*questions life* oh it was a typo, cool
vagrant@homestead:~/Code/lpg$ php artisan quote:generate
Never trust a developer wearing a suit.
vagrant@homestead:~/Code/lpg$ php artisan quote:generate
Give a man a fish and you feed him for a day, Teach a man to fish and you feed him for a
lifetime, Give a startup $$ and they’ll waste it.
vagrant@homestead:~/Code/lpg$ php artisan quote:generate
“The Top 100 JavaScript Frameworks of 2015″ ಠ_ಠ this is an issue.
Integration Options
We can also make use of options in the artisan command. Let’s add an option to
customize the greeting to the person running the command.
protected $signature = 'quote:generate {name=friend} {--greeting=check this out}';
We can now integrate this into our handle() method like so.
$this->info('Hey '.$this->argument('name').', '.$this->option('greeting').': '.$quotes[0]);
If there is one thing I love, it’s automatic code generation. There’s nothing quite
like having helpful commands and tools to scaffold out boilerplate code you
don’t feel like writing. In this tutorial, we’ll take a look at how Laravel, and
Artisan in particular, make it easy to add event functionality to your application.
Events are an implementation of the observer pattern, where an event takes
place, and then one or more listeners respond to that event. It can be thought of
like something making an announcement to your application, and then actions
being taken due to that announcement. Let’s see how we can set this up.
8 Steps To Success With Laravel Events
EventServiceProvider
You can begin setting up your events and listeners by populating the $listen array
in EventServiceProvider.php. As a quick example, let’s see if we can set up an event
where when a User logs in, we write that event to a file. Let’s see how to do that.
<?php
namespace App\Providers;
/**
* Register any other events for your application.
*
* @param \Illuminate\Contracts\Events\Dispatcher $events
* @return void
*/
public function boot(DispatcherContract $events)
{
parent::boot($events);
//
}
}
if (method_exists($this, 'authenticated')) {
return $this->authenticated($request, Auth::guard($this->getGuard())->user());
}
return redirect()->intended($this->redirectPath());
}
if (method_exists($this, 'authenticated')) {
return $this->authenticated($request, Auth::guard($this->getGuard())->user());
}
return redirect()->intended($this->redirectPath());
}
This snippet above is where the magic is starting to happen. Before the return statement is
issued, we added in some code to trigger our new event. We want to be able to determine
who it was that actually logged in. This is the reason for accepting the $request as a
parameter to the UserLoggedIn()instantiation. We will be able to access information about
the user via $request when we deal with it in our Listener class.
use App\Events\Event;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
/**
* Create a new event instance.
*
* @return void
*/
public function __construct()
{
//
}
/**
* Get the channels the event should be broadcast on.
*
* @return array
*/
public function broadcastOn()
{
return [];
}
}
At the trigger event location, recall that we wanted to pass in the $request object. We need
to update our UserLoggedIn event class to support this. Simply type hint it like so (and
add use Illuminate\Http\Request;).
<?php
namespace App\Events;
use App\Events\Event;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Http\Request;
public $user;
/**
* Create a new event instance.
*
* @return void
*/
public function __construct(Request $request)
{
$this->request = $request;
}
/**
* Get the channels the event should be broadcast on.
*
* @return array
*/
public function broadcastOn()
{
return [];
}
}
That’s about it for the Event class. Notice there really isn’t any logic in it. Mostly it is just a
data transfer object, or container for our event.
namespace App\Listeners;
use App\Events\UserLoggedIn;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
class WriteMessageToFile
{
/**
* Create the event listener.
*
* @return void
*/
public function __construct()
{
//
}
/**
* Handle the event.
*
* @param UserLoggedIn $event
* @return void
*/
public function handle(UserLoggedIn $event)
{
//
}
}
namespace App\Listeners;
use App\Events\UserLoggedIn;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Storage;
class WriteMessageToFile
{
/**
* Create the event listener.
*
* @return void
*/
public function __construct()
{
//
}
/**
* Handle the event.
*
* @param UserLoggedIn $event
* @return void
*/
public function handle(UserLoggedIn $event)
{
$message = $event->request->user()->name . ' just logged in to the application.';
Storage::put('loginactivity.txt', $message);
}
}
Hopefully you can see how we are accessing the $request object we had passed in. In our
Listener class, we simply access it as part of the type hinted Event class. So as we are
used to using something like $request->user() to access user information, in this case we
use something like $event->request->user(). In this file, we add use Storage at the top,
because we are going to write something to a file. We prepare the $message to be written
by accessing the user’s name, and concatenating a simple message to it. Once we have
our message, we use the Storage class to simply write it to a file.
Test It Out!
Ok, once we create a user, let’s try logging in.
Pretty Sweet! If you need more events and listeners, simply wash, rinse, repeat!
Interfaces are a huge part of the Laravel framework. You can also call them
contracts, this is how they are referred to on Github. This is the collection of
interfaces that the Laravel framework itself makes use of. By browsing the
contracts repository at Github, you can become familiar with the entire API of
the framework. All of the concrete classes of the framework implement these
various interfaces. In fact, when getting to know a software project, it is not a
bad idea to start by browsing all of the interfaces. This tells you what methods
will be available to you.
Cache Repository
As an example, we can take a look at the Cache repository.
<?php
namespace Illuminate\Contracts\Cache;
use Closure;
interface Repository
{
/**
* Determine if an item exists in the cache.
*
* @param string $key
* @return bool
*/
public function has($key);
/**
* Retrieve an item from the cache by key.
*
* @param string $key
* @param mixed $default
* @return mixed
*/
public function get($key, $default = null);
/**
* Retrieve an item from the cache and delete it.
*
* @param string $key
* @param mixed $default
* @return mixed
*/
public function pull($key, $default = null);
/**
* Store an item in the cache.
*
* @param string $key
* @param mixed $value
* @param \DateTime|int $minutes
* @return void
*/
public function put($key, $value, $minutes);
/**
* Store an item in the cache if the key does not exist.
*
* @param string $key
* @param mixed $value
* @param \DateTime|int $minutes
* @return bool
*/
public function add($key, $value, $minutes);
/**
* Increment the value of an item in the cache.
*
* @param string $key
* @param mixed $value
* @return int|bool
*/
public function increment($key, $value = 1);
/**
* Decrement the value of an item in the cache.
*
* @param string $key
* @param mixed $value
* @return int|bool
*/
public function decrement($key, $value = 1);
/**
* Store an item in the cache indefinitely.
*
* @param string $key
* @param mixed $value
* @return void
*/
public function forever($key, $value);
/**
* Get an item from the cache, or store the default value.
*
* @param string $key
* @param \DateTime|int $minutes
* @param \Closure $callback
* @return mixed
*/
public function remember($key, $minutes, Closure $callback);
/**
* Get an item from the cache, or store the default value forever.
*
* @param string $key
* @param \Closure $callback
* @return mixed
*/
public function sear($key, Closure $callback);
/**
* Get an item from the cache, or store the default value forever.
*
* @param string $key
* @param \Closure $callback
* @return mixed
*/
public function rememberForever($key, Closure $callback);
/**
* Remove an item from the cache.
*
* @param string $key
* @return bool
*/
public function forget($key);
}
By taking a look at this interface, we can see that any concrete implementation will need to
abide by the methods defined in the contract. We can see this would be things
like has(), get(), pull(), put(), add(), increment(), decrement(), forever(), remember(),
sear(), rememberForever(), and forget(). As we look at this, we can see this makes for
great documentation. Need to know what methods are available to you in a class? Just
look at the interface it implements. Laravel’s contracts component is a collection of
interfaces for all of the various APIs that the Framework makes available to users.
It is in this method where all of the default aliases and their mappings are declared. All of
this comes back to the concept of putting classes into the container and resolving objects
out of the service container, also known as the IoC container. It is because of the service
container and alias mapping that you can do things such as the following, that in effect are
all the same exact thing.
// use a facade
Route::get('/', function () {
return 'Interfaces are cool!';
});
Now, this is an example of the behavior we get for the built in routing class of Laravel. In
addition to all this flexibility and syntactic sugar, the other huge benefit of all these
contracts is that you can very easily swap out the default implementation with something
else. Personally, I have had no reason so far to ever need to do this. If you have a
situation where a particular requirement of a project demands that a particular class or
implementation of a component be used, then you are not out of luck. You can still use
Laravel, you just need to register your own component or class into the service container.
Then, when you ask for that interface in your code, you will be given the correct
implementation. Here is where you can learn more about the Laravel Service Container.
Let’s examine a little bit more about how this works.
Register With The Service Container (Put classes into the container)
You will often hear the phrase, “register to the service container”, or “bind into the service
container”. When I hear this, I simply think “Make classes available to the application by
way of the service container”. Think of the service container as a two way operation. We
register, or put classes into, the service container, and then later on we can resolve, or
take out of the service container, an object, or instance of any registered classes that we
might like to make use of. This usually happens with the register() method of a service
provider. For example, here is that very registration for the Cache component of Laravel.
public function register()
{
$this->app->singleton('cache', function ($app) {
return new CacheManager($app);
});
$this->app->singleton('memcached.connector', function () {
return new MemcachedConnector;
});
$this->registerCommands();
}
We can see that it is the singleton() method which does the work for us. This is mostly the
same as if you were to call the bind() method. The difference between the two is that the
singleton pattern is going to give the developer a shared instance of the object at all times.
A new object is not created every time. Now in the snippet above, there are a few options
for various keys. Those are cache, cache.store, and memcached.connector. Which one gets
resolved depends on the configuration of the application. When a request is made of one
of those keys, it is the closure that will return an instance of the given class.
Here is that singleton() method which is part of the Container class.
public function singleton($abstract, $concrete = null)
{
$this->bind($abstract, $concrete, true);
}
This method actually makes use of the bind() method, but it sets the third parameter
to true, which indicates that this is a shared instance. Here is that bind() method.
public function bind($abstract, $concrete = null, $shared = false)
{
$abstract = $this->normalize($abstract);
$concrete = $this->normalize($concrete);
// If the given types are actually an array, we will assume an alias is being
// defined and will grab this "real" abstract class name and register this
// alias with the container so that it can be used as a shortcut for it.
if (is_array($abstract)) {
list($abstract, $alias) = $this->extractAlias($abstract);
$this->alias($abstract, $alias);
}
// If no concrete type was given, we will simply set the concrete type to the
// abstract type. This will allow concrete type to be registered as shared
// without being forced to state their classes in both of the parameter.
$this->dropStaleInstances($abstract);
if (is_null($concrete)) {
$concrete = $abstract;
}
// If the abstract type was already resolved in this container we'll fire the
// rebound listener so that any objects which have already gotten resolved
// can have their copy of the object updated via the listener callbacks.
if ($this->resolved($abstract)) {
$this->rebound($abstract);
}
}
Resolve Out of The Service Container (Get Objects out of the container)
Resolving objects out of the service container simply means that when you go to use a
component or object in your application code, it is the service container that handles
building up any dependencies and requirements needed to simply hand over an object that
is ready to do it’s work. It’s a convenience for the developer, and mostly happens with out
you even realizing it.
Consider the app() helper function, which calls a make() method on the application class.
if (! function_exists('app')) {
/**
* Get the available container instance.
*
* @param string $make
* @param array $parameters
* @return mixed|\Illuminate\Foundation\Application
*/
function app($make = null, $parameters = [])
{
if (is_null($make)) {
return Container::getInstance();
}
if (isset($this->deferredServices[$abstract])) {
$this->loadDeferredProvider($abstract);
}
Again, the comments help us understand what is happening. Ultimately the work is being
done by the make() method of the Container, which is the Application parent. Here is that
make() method.
public function make($abstract, array $parameters = [])
{
$abstract = $this->getAlias($this->normalize($abstract));
$concrete = $this->getConcrete($abstract);
// If we defined any extenders for this type, we'll need to spin through them
// and apply them to the object being built. This allows for the extension
// of services, such as changing configuration or decorating the object.
foreach ($this->getExtenders($abstract) as $extender) {
$object = $extender($object, $this);
}
$this->fireResolvingCallbacks($abstract, $object);
$this->resolved[$abstract] = true;
return $object;
}
We can see that after all the logic of this method happens, finally we are returned an
Object. It is this object which is an instance of whatever you asked for in your application
code. In other words, depending on the key you asked for, you get the desired (Object |
Service | Component) back.
One thing to note in the make() method of the Application class, is that it makes use of
a getAlias()method. This is how you are able to pass the key, alias, class, or contract, to
the app() method, and the framework knows how to resolve everything correctly. Here is
that very method.
protected function getAlias($abstract)
{
return isset($this->aliases[$abstract]) ? $this->aliases[$abstract] : $abstract;
}
We can see it makes use of a convenient ternary operator to check if there is already an
alias registered, and if so just return it. If not, we return the value of the $abstract variable
which is most likely the key. This is how the contract or interface would be normalized into
a standard alias key. In other words, if you pass something
like Illuminate\Contracts\Routing\Registrar the software can translate this to the key
of router.
Laravel Aliases and Contracts Summary
In this tutorial, we took a closer look at the aliases and contracts component of Laravel.
We found that the interfaces themselves act as great documentation to help a developer
explore the api that is exposed by any given class of the framework. We also dug into how
when instantiating objects via the service container, there is a lot of flexibility in how to go
about doing that. By looking closely at how all of this works, we can see how the Container
and Application classes are really the meat and potatoes of Laravel. We register classes
into the service container, and fetch objects out of it as needed. This is a key foundation of
how Laravel works.
Testing is not something I’ve personally ever put a lot of time in to. If the code I
was writing did what I wanted it to do, that was good enough for me. If formal
testing is not part of your background, the benefits of testing are not all that
obvious. In fact, being new to testing myself, some of the benefits are not
obvious to me. Mostly, I’d like to take a dive into testing with Laravel because it
is a new challenge and something fun to tinker with and learn. As we go, let’s
see if we can uncover some of the benefits and advantages to test driven
development. At the end of this tutorial, we will try to answer the question: Why
should I write tests?
So far this file does not mean a lot to us, but we’ll see if we can learn about it as we move
forward. We can make some generalized assumptions though such as there is
a /tests directory and an /appdirectory to be aware of, as well as an autoload file for the
bootstrap. Let’s get to that first magical test by typing phpunit at the command line like so.
Wow this looks pretty cool! Let’s see what we did here. First we had to ssh into the
homestead box, as we need to run tests on the virtual machine, not the host computer.
Then, we change into the directory which holds our application. In our case we had to cd
Code, then cd lpg. Finally, we are ready to run our very first Test! At the command line
from the root of our project we run phpunit. The output as we can see is OK with a green
background. We can also see there was 1 test and 2 assertions. So what does this
actually mean?
It turns out, there is an ExampleTest.php that already lives in the tests directory of our
project. This is the file which ran when we just typed phpunit at the command line. So what
does this file contain? Let’s have a look.
<?php
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\DatabaseTransactions;
Just by looking at the code we can infer that by visiting the root of our project, we
Pretty cool!
will see the text of Laravel. If we manually visit the page in our browser, this is in fact what
we see.
Micro Summary: This first example was simply inspecting the default test that ships with
Laravel. In it we see how to make use of the visit() and see() methods. We also ran
the phpunit command at the command line to test things out.
namespace App\Http\Controllers;
use Illuminate\Http\Request;
Before we even try to use this function, we will create a test for it. We can use artisan to do
this for us. We’ll create a test class to test the HomeController class. We do so by
typing php artisan make:test HomeControllerTest. This creates a new test class for us,
and it looks like this.
<?php
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\DatabaseTransactions;
So now we have two files for testing in our tests directory, both
the ExampleTest.php and HomeControllerTest.php. We’ll need to update our new test class
to test the function in our controller. Let’s update the HomeControllerTest.php file to
actually test our add function in the HomeController.
<?php
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\DatabaseTransactions;
What we are doing here is to create the test. We name it test_add() since that is what we
are trying to confirm. First off, we set up some data. This is the first number and second
number to add. Then, we make a call to our function, passing in two number arguments.
We know that 1 + 1 should be 2. Now let’s tell our test case that this is what is supposed
to happen. Notice we make use of the PHP Unit method assertEquals(). This function
simply verifies or asserts if argument 1 and argument 2 are equal. So since we know that 1
+ 1 should equal 2, we assign this as the first parameter to assertEquals(). We pass
the $sum that our add() function returns as argument 2. Let’s test it by running phpunit.
Cool! Our test is passing. Let’s make a change and see what happens.
public function test_add()
{
$num1 = 2;
$num2 = 3;
$sum = \App\Http\Controllers\HomeController::add($num1, $num2);
$this->assertEquals(2, $sum);
}
Now notice that we pass 2 and 3 as the arguments to our add() function. In
our assertEquals()function, we are leaving 2 as the first argument. What this is saying is
that 2 + 5 should equal 2, and we know that is not true, so our test should fail. Let’s see if
it does.
This is what a failing PHP Unit test looks like. In our case, it tells us exactly what went
wrong. Failed asserting that 5 matches expected 2. Let’s make our test pass again. We will
simply change our expected result from 2 to 5 like so.
$this->assertEquals(5, $sum);
• 1. Visit /pageone
• 2. Click on the “Page Two” link
• 3. See Page Two
• 4. Assert that the current url is /pagetwo
Running phpunit again, and we get another error. It looks like we blew up the server again.
There was 1 failure:
1) ExampleTest::testBasicExample
A request to [http://localhost/pagetwo] failed. Received status code [500].
Oh right, we need to add a view for pagetwo. Create pagetwo.blade.php and run phpunit
again.
There was 1 error:
1) ExampleTest::testBasicExample
InvalidArgumentException: The current node list is empty.
Hmmm, maybe this is because we did not add the text on page two yet. Add the text, “This
is page two” to this view, then run phpunit again.
vagrant@homestead:~/Code/lpg$ phpunit
PHPUnit 5.5.2 by Sebastian Bergmann and contributors.
. 1 / 1 (100%)
Time: 319 ms, Memory: 10.00MB
OK (1 test, 5 assertions)
vagrant@homestead:~/Code/lpg$
Nice! It is now fully working!
Even though our test only used four methods, there is a lot of horsepower there. Looking
at the source code that makes this possible shows us how it works.
visit()
// Visit the given URI with a GET request.
click()
// Click a link with the given body, name, or ID attribute.
if (! count($link)) {
$link = $this->filterByNameOrId($name, 'a');
if (! count($link)) {
throw new InvalidArgumentException(
"Could not find a link with a body, name, or ID attribute of [{$name}]."
);
}
}
$this->visit($link->link()->getUri());
return $this;
}
see()
// Assert that a given string is seen on the current HTML.
seePageIs()
// Assert that the current page matches a given URI.
$this->assertEquals(
$uri, $this->currentUri, "Did not land on expected page [{$uri}].\n"
);
return $this;
}
In addition to all of the common functionality we’ve come to know and love in
Laravel such as routing, mail, file storage, middleware, authentication, and
more, Laravel also provides some pretty cool helper functions to make common
tasks easier. In this episode we’ll take a look at some of the string helpers that
are included with Laravel and test them out to see how they work. Let’s check it
out now.
camel_case()
First we’ll check out the camel_case() function that accepts a string, and then converts it to
camel case. For example:
$camelfied = camel_case('this-is_a_-string');
echo $camelfied;
// thisIsAString
This is pretty cool, let’s see how it works. In the helpers.php file we find the code that
references this function. Here it is:
if (! function_exists('camel_case')) {
/**
* Convert a value to camel case.
*
* @param string $value
* @return string
*/
function camel_case($value)
{
return Str::camel($value);
}
}
We can see that it is calling on a static method of camel, so let’s go see how that works. In
the Str class we find it here:
public static function camel($value)
{
if (isset(static::$camelCache[$value])) {
return static::$camelCache[$value];
}
Interesting. First, it looks like the value is converted to studly case, then that result is run
through the lcfirst function making the first character lowercase. This studly function is
part of this same class so let’s have a look at how that works.
public static function studly($value)
{
$key = $value;
if (isset(static::$studlyCache[$key])) {
return static::$studlyCache[$key];
}
So we can see that first off, the str_replace function is used to look for any hyphen or
underscore characters in the string, and replace them with a blank space. Once this is
complete, the ucwords function is applied creating a string like so:
$value = 'this-is_a_-string';
// This Is A String
This result is once again put through the str_replace function and any blank spaces are
removed from the string.
$value = 'This Is A String';
// ThisIsAString
Finally, the lcfirst function is applied to this result in the public static function camel,
resulting in our camel case string, thisIsAString.
class_basename()
Next up is the class_basename() function which gives you the base class of a namespaced
representation of the class. For example:
$basename = class_basename('App\Http\Requests');
echo $basename;
// Requests
Let’s see how it works. Again in the helpers.php file we find the following.
if (! function_exists('class_basename')) {
/**
* Get the class "basename" of the given object / class.
*
* @param string|object $class
* @return string
*/
function class_basename($class)
{
$class = is_object($class) ? get_class($class) : $class;
e()
Moving along and we come to the e() helper function, which makes it a whole lot easier to
make use of the htmlentities function in PHP. Let’s test it out now:
$html = '<div class="boo">Technology</div>';
echo e($html);
// <div class="boo">Technology</div>
ends_with()
The ends_with() function checks a string to see if it ends with a particular value. Let’s try it
out.
$string = 'God Bless America';
// 1 or true
return false;
}
//--------------------------//
snake_case()
This function takes a string and turns it into snake case. Let’s try it on the string we initially
turned into a camel case. Recall we turned this-is_a_-string into thisIsAString using
the camel_case() function. Let’s now put that result through the snake_case() function.
$string = 'thisIsAString';
echo snake_case($string);
// this_is_a_string
Upon inspecting the code, we found that you can also pass a second parameter to create
your own version of the snake case. You can even do a umadbro emoji like so:
$string = 'thisIsAString';
// this¯\_(ツ)_/¯is¯\_(ツ)_/¯a¯\_(ツ)_/¯string
This is really cool! The snake_case() is actually fairly involved in how it works making use
of regular expressions to make the magic happen.
str_limit()
This function is very handy for when you want to show a block of text, such as in a card
based layout, where all blocks of text are the same length so that the display is uniform.
Basically, you pass this function a string of text as the first parameter and the number of
characters you would like to display as the second argument. Here is an example:
$real_long_string = 'supercalifragilisticexpialidocious';
// super...
starts_with()
The starts_with() function can be used to check if a string starts with a given value.
$thestring = 'Ready. Set. Go!';
// 1 or true
str_contains()
Finding a value in a string is such a common task in PHP and many times we make use of
strpos to complete this. Think of str_contains() as a more robust version of strpos() with an
easier to reason about naming convention. Let’s see it in action here:
$stringvalue = 'Oh say can you see, by the dawn\'s early light';
// 1 or true
You can also check if the string contains multiple values using an array like so:
echo str_contains($stringvalue, ['see', 'light', 'Oh']);
// 1 or true
str_finish()
The str_finish() function acts like a string concatenator of sorts by adding a value to the
end of the string. Here is our test of str_finish()
$string = 'Bae, can you do me a favor';
str_is()
This function can be used to test for the occurrence of a pattern in a string, and you can
use one or more wildcards for the pattern. Here are a few examples.
$string = 'Here we have a pattern';
str_plural()
The str_plural() function takes a word, and returns the plural form of it.
echo str_plural('Truck');
// Trucks
echo str_plural('House');
// Houses
str_singular()
In addition to being able to pluralize a word, we can convert back to the singular with the
str_singular() function. Let’s try it out.
echo str_singular('Children');
// Child
str_random()
If you need to generate a random string with a specific length, this is the function to do it.
Here we are generating a random string 30 characters in length.
echo str_random(30);
// 6ypXOYMTHcze0AhM6xJRRtzOD31UTZ
str_slug()
The str_slug() function is perfect to sluggify any string. For example:
echo str_slug('Soon this string will be sluggified');
// soon-this-string-will-be-sluggified
studly_case()
The studly_case() function is used to apply a studly case to a string. This means each
significant word begins with an uppercase letter, including the first letter of the string. Let’s
see it work.
echo studly_case('we can_turn--this__to studly');
// WeCanTurnThisToStudly
title_case()
Similar to the studly case scenario we just examined is the title_case() function which
works in a similar way, but adds a space between the words. Turn any string into a title in
a snap.
echo title_case('10 tips for working with strings');
// 10 Tips For Working With Strings
In this installment, we’ll examine a cool Laravel AJAX CRUD Tutorial. There are
a few benefits to handling database interactions with ajax. We know that it
helps to make page updates very quick, reduces the amount of bandwidth
used, and provides for a slick user experience. We’ll make use of Laravel on
the backend and jQuery on the client side to set up a fully functioning Laravel
ajax crud tutorial application.
1. Create a Model and a Migration
First off, we are going to create a Model to represent the entities we will be creating,
reading, updating and deleting. In our case we will use the concept of a Link. Let’s use
artisan to create the model and migration for us in one step.
php artisan make:model Link -m
This command creates both a Link Model and an associated migration. We can open the
model found in /app/Link.php now.
/app/Link.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
namespace App;
use Illuminate\Database\Eloquent\Model;
/database/migrations/xxxx_xx_xx_xxxxxx_create_links_table.php
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
use App\Link;
Link::create([
'url' => 'https://laravel.com/',
'description' => 'Laravel - The PHP framework for web artisans.',
]);
Link::create([
'url' => 'https://laracasts.com/',
'description' => 'The best PHP and Laravel screencasts on the web.',
]);
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('links');
}
}
In the .env file we simply change the database to laracrud and leave the other settings at
their defaults.
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laracrud
DB_USERNAME=homestead
DB_PASSWORD=secret
//--CREATE a link--//
Route::post('/links', function (Request $request) {
$link = Link::create($request->all());
return Response::json($link);
});
//--UPDATE a link--//
Route::put('/links/{link_id?}', function (Request $request, $link_id) {
$link = Link::find($link_id);
$link->url = $request->url;
$link->description = $request->description;
$link->save();
return Response::json($link);
});
//--DELETE a link--//
Route::delete('/links/{link_id?}', function ($link_id) {
$link = Link::destroy($link_id);
return Response::json($link);
});
@yield('content')
<script src="js/3.1.1.jquery.min.js"></script>
<script src="js/1.3.7.tether.min.js"></script>
<script src="js/4.0.0-alpha.5.bootstrap.min.js"></script>
<script src="js/laracrud.js"></script>
</body>
</html>
/resources/views/laracrud.blade.php
In our partial view file, we are able to set up a few things. First, we make use of a nice
card, which is new in Bootstrap 4, to display a little information about our small app, as
well as to provide a button to add a new link. After this, we make use of another cool new
feature in Bootstrap 4, and that is the inverse table which makes for some cool styling
effects. Finally, we have a modal, which of course is not displayed until we actually need to
add or edit a link. The interesting thing about this modal is that it will be massaged by
jQuery to make sure it contains the right information before displaying that modal. This way
we can use the same modal whether adding a link, or editing a link.
@extends('layouts.app')
@section('content')
<div class="container">
<div>
<table class="table table-inverse">
<thead>
<tr>
<th>ID</th>
<th>Link</th>
<th>Description</th>
<th>Edit or Delete</th>
</tr>
</thead>
<tbody id="links-list" name="links-list">
@foreach ($links as $link)
<tr id="link{{$link->id}}">
<td>{{$link->id}}</td>
<td>{{$link->url}}</td>
<td>{{$link->description}}</td>
<td>
<button class="btn btn-info open-modal" value="{{$link->id}}">Edit
</button>
<button class="btn btn-danger delete-link" value="{{$link->id}}">Delete
</button>
</td>
</tr>
@endforeach
</tbody>
</table>
<div class="form-group">
<label for="inputLink" class="col-sm-2 control-
label">Link</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="link" name="link"
placeholder="Enter URL" value="">
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">Description</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="description"
name="description"
placeholder="Enter Link Description" value="">
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" id="btn-save"
value="add">Save changes
</button>
<input type="hidden" id="link_id" name="link_id" value="0">
</div>
</div>
</div>
</div>
</div>
</div>
@endsection
public/js/laracrud.js
$(document).ready(function () {
////----- Open the modal to CREATE a link -----////
$('#btn-add').click(function () {
$('#btn-save').val("add");
$('#modalFormData').trigger("reset");
$('#linkEditorModal').modal('show');
});
composer
This command launches the Composer software and tells it your ready to do something. If
you only type this command at the terminal, you will see something like this. It gives you a
chance to view many of the available commands you can use.
create-project
This command is the equivalent of using git to clone a project, then running a composer
install to download all dependencies in the project. So it’s a shortcut in essence, and it
works really well.
–prefer-dist
First we must know what dist stands for. dist is short for distribution, and in open source
software, this is usually the location that contains distribution or ready to use software.
There is no compilation step or build process needed as in contrast to source. By using the
–prefer-dist flag, we are telling composer that we want this ready to use software.
laravel/laravel
This portion of the command is denoting that we want the laravel vendor and the laravel
package. It is in the format of vendor/package.
54
This tells composer that we want a folder named 54, and that we want to place the entire
contents of this project in that folder. We could name this anything we like. We only chose
54 since we are using Laravel 5.4 in this example.
So now that we understand exactly what this command does for us, we run it and watch
the magic happen. You might see something like this in your terminal.
When everything finishes, you will have all the files you need in your folder to begin a
Laravel Project. We now navigate over to PHP Storm and choose File->Open to open the
directory we just put all of our code in. So in our case, we are opening the 54 directory.
Behold, your Laravel Installation.
There’s a lot going on here! Fear not, all we need to worry about right now is
that routes folder. Since we are looking at basic routing and views in this article, that is
what is highlighted in the image. If you open this folder up, you’ll see four files. These
include api.php, channels.php, console.php, and web.php. It is the web.php file that we
want to look at now.
<?php
Route::get('/', function () {
return view('welcome');
});
Looks good! What we see here is a method which accepts two arguments. Don’t let the
code formatting confuse you. Route::get( ); is the method being called, and the two
arguments are inside the parenthesis separated by a comma. Think of it like
Route::get(arg1, arg2 ); The first argument determines where an http request is being
made to. We can see one forward slash here. This represents someone making a request
to view your site at the root or domain level. The second argument is the action to take
when this request is made. You can use a Closure like shown here, of a controller. We’ll
stick to the simple Closure for now. This is an anonymous function which runs immediately
when a request is made. What does this function do? It returns, or renders, the welcome
view. If we visit the root level of our new project in a browser, we can see this working in
action.
Route::get('/', function () {
return view('welcome');
});
// Our custom Laravel route
Route::get('hello', function(){
return view('hello');
});
You can see our new route in place. It simply says that if someone makes request to view
http://mysite/hello, then the Closure will execute and it will load a view named hello. Try it
in your browser now.
In the resources folder, there are three additional folders named assets, lang, and views.
We will create a file named hello.blade.php inside the views folder. Here it is, in all of it’s
glory.
<h1>Hello!</h1>
Let us now try visiting our /hello route once more in the browser.
We have created our first custom route and view in Laravel, and it is working like a champ!
/routes/web.php
<?php
Route::get('games', function () {
return view('games');
});
/resources/views/games.blade.php
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Games</title>
</head>
<body>
<ul>
<li>Castlevania</li>
<li>Galaga</li>
<li>Ghosts n Goblins</li>
</ul>
</body>
</html>
http://54.dev/games
/routes/web.php
<?php
Route::get('games', function () {
return view('games', [
'games' => ['Castlevania', 'Galaga', 'Ghosts n Goblins']
]);
});
/resources/views/games.blade.php
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Games</title>
</head>
<body>
<ul>
<?php foreach ($games as $game) : ?>
<li><?= $game; ?></li>
<?php endforeach; ?>
</ul>
</body>
</html>
http://54.dev/games
As we can see, the data is now dynamic. It is being passed as an array from the routes file
to the view for rendering. It’s important to note that it is the second argument passed to
the view() function which holds the dynamic data. That second argument is to be an array.
Now, the keys of that array become the variable names in the view. So in our example
here, that second argument is an array which has only one key which is games.
That games key itself holds an array of the three games we wish to pass to the view. Then,
in the view, we use a standard PHP foreach construct to loop over each game and output
the result. Need to see proof that this is dynamic? Let’s go ahead and update the array of
data we are passing and then observe the result in the browser. (The view file is
unchanged at this point).
/routes/web.php
<?php
Route::get('games', function () {
return view('games', [
'games' => ['Balloon Fight', 'Donkey Kong', 'Excitebike']
]);
});
http://54.dev/games
Inline
<?php
Route::get('games', function () {
return view('games', [
'games' => ['Balloon Fight', 'Donkey Kong', 'Excitebike']
]);
});
Setting up a data array
<?php
Route::get('games', function () {
$data['games'] = ['Balloon Fight', 'Donkey Kong', 'Excitebike'];
return view('games', $data);
});
Route::get('games', function () {
$games = ['Balloon Fight', 'Donkey Kong', 'Excitebike'];
return view('games')->with('games', $games);
});
Route::get('games', function () {
$games = ['Balloon Fight', 'Donkey Kong', 'Excitebike'];
return view('games', compact('games'));
});
Since the $data variable is an array, it can contain as many keys as you may ever need to
store data. So let’s consider that not only do we want to list the Games, but also
the Publishers of those games as well. How might we do that? Let’s see!
/routes/web.php
<?php
Route::get('games', function () {
/resources/views/games.blade.php
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Games</title>
</head>
<body>
<table border="1">
<tr>
<th>Game</th>
<th>Publisher</th>
</tr>
<?php for($i = 0; $i < count($games); $i++) : ?>
<tr>
<td><?= $games[$i]?></td>
<td><?= $publishers[$i]?></td>
</tr>
<?php endfor ?>
</table>
</body>
</html>
http://54.dev/games
Maybe you also want to include the Year the game was released as well. It’s very
Fantastic!
easy to scale this up, and all you ever have is that same $data variable as the second
argument to view().
/routes/web.php
<?php
Route::get('games', function () {
/resources/views/games.blade.php
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Games</title>
</head>
<body>
<table border="1">
<tr>
<th>Game</th>
<th>Publisher</th>
<th>Release Date</th>
</tr>
<?php for($i = 0; $i < count($games); $i++) : ?>
<tr>
<td><?= $games[$i]?></td>
<td><?= $publishers[$i]?></td>
<td><?= $releasedates[$i]?></td>
</tr>
<?php endfor ?>
</table>
</body>
</html>
http://54.dev/games
Of course you can use whichever approach works best for you. We all learn differently,
and surely some of us will like one approach and others will take a different approach. It all
depends on what makes the most sense in your own mind. Always try to make it easy on
yourself.
// blade
<ul>
@foreach ($games as $game)
<li>{{ $game }}</li>
@endforeach
</ul>
If we take the table we rendered earlier, we can also update that to use blade.
// php
<table border="1">
<tr>
<th>Game</th>
<th>Publisher</th>
<th>Release Date</th>
</tr>
<?php for($i = 0; $i < count($games); $i++) : ?>
<tr>
<td><?= $games[$i]?></td>
<td><?= $publishers[$i]?></td>
<td><?= $releasedates[$i]?></td>
</tr>
<?php endfor ?>
</table>
// blade
<table border="1">
<tr>
<th>Game</th>
<th>Publisher</th>
<th>Release Date</th>
</tr>
@for($i = 0; $i < count($games); $i++)
<tr>
<td>{{ $games[$i] }}</td>
<td>{{ $publishers[$i] }}</td>
<td>{{ $releasedates[$i] }}</td>
</tr>
@endfor
</table>
Now that we’ve covered the most simple introduction to Laravel, let’s take a
moment to get ready to work with a database so we can make use of the Query
Builder or Eloquent. You have many options to choose from such as sqlite,
pgsql, redis, and mysql. MySql is far and away the most used option, so that is
what we’ll look at here. In addition, we can work with the database via the
command line, or from a graphical user interface such as phpMyAdmin. We’ll
take a look at both options in this tutorial.
Log in to mysql
Once you are logged in to the VM, you can easily go to the MySQL command line by
simply typing mysql and hitting enter.
Create a new database to work with
Let’s go ahead and first look at what is in the database by typing show databases;. We see
a few of them such as information_schema, homestead, mysql, performance_schema, and
sys. We want to create a custom database for this so we type create database '54'; and
note that we get a result of Query OK, 1 row affected. If we show the databases again we
see our new database.
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('users');
}
}
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('password_resets');
}
}
Database setup is complete!
Laravel is now connected to and working with your local database. We now have all the
plumbing set up and configured for working with MySql.
authorize: ~/.ssh/id_rsa.pub
keys:
- ~/.ssh/id_rsa
folders:
- map: C:/localdev
to: /home/vagrant/Code
sites:
- map: phpmyadmin.dev
to: /home/vagrant/Code/phpmyadmin
- map: homestead.app
to: /home/vagrant/Code/Laravel/public
- map: 54.dev
to: /home/vagrant/Code/54/public
databases:
- homestead
# blackfire:
# - id: foo
# token: bar
# client-id: foo
# client-token: bar
# ports:
# - send: 50000
# to: 5000
# - send: 7777
# to: 777
# protocol: udp
We’re moving forward with Laravel and so far we have a good grasp of routing,
views, and we have also set up our environment with a database connection.
We also included phpMyAdmin as a graphical front end to the database so that
manually working with tables and data is easy. Recall that in our passing data
to views tutorial, we simply hard coded the data in the Closure of our routes file.
We’ll take it even further in this episode, and being working with dynamic data
from a database.
When we open the file, it has the following code to help get us started.
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
At this point, we do need to edit the file ourselves to match the data we are trying to hold.
By default, the table already has an id column and a timestamps column. Almost all
tables will use these two, so we leave them in place. What we don’t have yet are the
specific columns for the title of a game, the publisher of a game, and the releasedate of
a game. It is in the up() function where we can define database columns, so let’s do that
now.
public function up()
{
Schema::create('games', function (Blueprint $table) {
$table->increments('id');
$table->string('title');
$table->string('publisher');
$table->integer('releasedate');
$table->timestamps();
});
}
We now have Mega Man 2, Metroid, and Tecmo Bowl as some sample data to
Pretty Cool!
work with. So let’s get cooking with the Laravel Query Builder to get access to this data.
Route::get('games', function () {
$games = DB::table('games')->get();
Route::get('games', function () {
$games = DB::table('games')->get();
dd($games);
});
Render As JSON
<?php
Route::get('games', function () {
$games = DB::table('games')->get();
return $games;
});
Route::get('games', function () {
$games = DB::table('games')->get();
Excellent. We can see that $games is an instance of, or object, of the class
Illuminate\Support\Collection. Contained in the collection object is an array. This array
holds one or more objects of type stdClass. So a collection is an array of objects. By
looking at one of the ways to inspect this collection that we just demonstrated, we can
figure out how to access individual values in the collection.
routes/web.php
<?php
Route::get('games', function () {
$games = DB::table('games')->get();
resources/views/games.blade.php
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Games</title>
</head>
<body>
<table border="1">
<tr>
<th>Game</th>
<th>Publisher</th>
<th>Release Date</th>
</tr>
@for($i = 0; $i < count($games); $i++)
<tr>
<td>{{ $games[$i]->title }}</td>
<td>{{ $games[$i]->publisher }}</td>
<td>{{ $games[$i]->releasedate }}</td>
</tr>
@endfor
</table>
</body>
</html>
Route::get('games', function () {
$games = DB::table('games')->where('title','Metroid')->get();
routes/web.php
<?php
Route::get('games', function () {
$games = DB::table('games')->latest()->get();
$game = DB::table('games')->find($id);
This is our updated routes file. There are a few things to note. In the /games route, notice
that the query builder is making use of a latest() method. This fetches all games and
orders them by the most recently added to the database. That’s a nice little feature. Next
up, notice that first argument to the view() function. It is specified as games.index. What
this means is, Laravel should look in a games folder contained within the views folder to
find the index.blade.php file.
Moving on to our new route of /games/{id}, we find a new syntax here. The {id} portion of
the route is a wildcard operator so that an id can be passed to the query via the URL
which is used in the browser. Our route closure then captures that id, and uses it with
the find() function to get a particular record. Additionally, the view() function in this route
is having games.show passed as the first argument. Again this means Laravel will look in
the games folder located in the views folder for a file named show.blade.php. Let’s create
those new view files now.
resources/views/games/index.blade.php
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Games</title>
</head>
<body>
<ul>
@foreach($games as $game)
<li><a href="/games/{{ $game->id }}">{{ $game->title }}</a></li>
@endforeach
</ul>
</body>
</html>
resources/views/games/show.blade.php
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Game</title>
</head>
<body>
</body>
</html>
Check out the fruits of our labor!
app/Game.php
The Game class extends the Eloquent Model class.
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
Route::get('games', function () {
$games = App\Game::all();
This snippet gets all of the games in the database as a collection, just like in our query
builder tutorial.
use App\Game;
Route::get('games', function () {
$games = Game::all();
$game = Game::find($id);
By simply typing new Game;, a new instance of our Game Model is created. Remember that
our games table has several columns. Let’s recall what they are.
Columns are also called Fields. So we can see fields
of id, title, publisher, releasedate, created_at, and updated_at. Here is what is so cool.
Those fields in the database table map directly to property names on the Model object!
What that means is that we can simply assign values to them, just as we would any other
object in PHP. When you’re finished assigning values, all you have to do is call
the save() method on the object, and the data is saved right into that table. So Cool! Let’s
add another game.
Now you might be wondering why we did not have to worry about
the id or timestamp fields. This is because these fields are handled automatically in the
database or by Eloquent. The id field is an auto increment field, which means it’s value will
go up by one every time a new record is added to the database. This way, every single
record in the database will have it’s own unique id. MySql takes care of this for us.
The timestamps are handled automatically by Eloquent, so we’ll never have to manually
set those.
Let’s look at all the games again. This time, we’ll just update our routes file so that we can
inspect them. We’ll also give ourselves some ideas on how to add constraints to the query
to get specific games from the database.
use App\Game;
Route::get('games', function () {
$games = Game::all();
return $games;
});
[
{
"id": 1,
"title": "Mega Man 2",
"publisher": "Capcom",
"releasedate": 1989,
"created_at": "2017-04-04 17:51:48",
"updated_at": "2017-04-04 17:51:48"
},
{
"id": 2,
"title": "Metroid",
"publisher": "Nintendo",
"releasedate": 1986,
"created_at": "2017-04-04 17:58:37",
"updated_at": "2017-04-04 17:58:37"
},
{
"id": 3,
"title": "Tecmo Bowl",
"publisher": "Koei Tecmo",
"releasedate": 1989,
"created_at": "2017-04-04 17:59:08",
"updated_at": "2017-04-04 17:59:08"
},
{
"id": 4,
"title": "The Legend of Zelda",
"publisher": "Nintendo",
"releasedate": 1986,
"created_at": "2017-04-05 22:35:04",
"updated_at": "2017-04-05 22:35:04"
},
{
"id": 5,
"title": "Ninja Gaiden",
"publisher": "Koei Temco",
"releasedate": 1988,
"created_at": "2017-04-05 22:54:15",
"updated_at": "2017-04-05 22:54:15"
}
]
If you look at the id’s of the two results returned, we can see both of them have a value
which is larger than 3. So our query worked!
How about getting a game which has the word Mega in the title. Coming right up.
So this is pretty cool. We have a good understanding of where( ) and how to make use of
it, and make use of it you will. All the time!
orderBy() can be applied to Eloquent queries to order the results by a particular field in the
table. By default, orderyBy() sorts the results in ascending order. If you pass the optional
second argument with a string of ‘desc’, you can sort the results in descending order. Let’s
try an example.
Order all games by the id field in descending order.
Game::orderBy('id', 'desc')->get();
Limiting The Number of Results with take(), and introducing command chaining
Limiting the number of results a particular query should return is a very common operation.
In Eloquent, we can make use of the take() command and pass it a number value to
represent the number or records we want. In addition, we will show an example of chaining
commands together. This is what’s known as a fluent interface. Let’s see an example here.
Get three records ordered by their releasedate in descending order.
Game::orderBy('releasedate', 'desc')->take(3)->get();
If you only want a specific field from the table, you can use pluck() like so.
Game::pluck('title');
Now, what we are going to do is set up a basic eloquent query without calling get() and
assigning the result to a variable. An instance of Illuminate\Database\Eloquent\Builder is
assigned to that variable. What this means is that you can then add commands to that
instance one at a time, as you see fit. When you’re ready to actually trigger the query, you
can then call get(). Let’s see this idea in practice.
So you can see that when we write something like $game = Game::where(‘publisher’, ‘=’,
‘Nintendo’); – we are putting an instance of the query builder into the $game variable. We
can then call additional commands on that variable. This is a process of ‘building up’ a
query so to speak. When you’re ready to execute the query, you just call $game->get(); to
fire it off. For this getting started tutorial, this concept is not critical. When you start getting
into advanced Eloquent, this becomes more important.
The query above is the same as if it were written like so:
$games = Game::where('publisher', '=', 'Nintendo')
->orderBy('releasedate', 'desc')
->take(3)
->get();
select * from games where publisher = ‘Nintendo’ order by releasedate desc limit 3;
Introduction to Query Scopes
What if I told you, you could type something like Game::nintendo()->get(); and have all the
games by Nintendo retrieved out of the database? Well, I’m telling you that, so let’s see
how we can do this!
Open up the Games.php Model, and add the following code.
app/Games.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use App\Game;
Route::get('/', function () {
return Game::nintendo()->get();
});
Well, well, well! That does indeed look pretty cool! So to create a query scope, you do the
following.
use App\Game;
Route::get('/', function () {
return Game::nintendo()
->where('title', 'like', '%Mario%')
->get();
});
Deleting a Model
There are a few ways to delete records in the table. Here we delete a single game by it’s
id. We then delete multiple games at once based on the name of the publisher.
If you wanted to, you could build a pretty substantial application and never
make use of a controller. How could this be? Well, we saw in our introduction to
basic routing and views that we can pass a closure to the second argument of a
Route::get() request. The drawback is that pretty soon, you are going to have a
routes file the size of Manhattan, and that is probably not ideal. We just want
the routes file to direct traffic, not do any heavy lifting. To accomplish this goal,
we will now start making use of dedicated controllers in our little games
application. Let’s see how to get them set up.
use App\Game;
Route::get('games', function () {
$games = Game::all();
return view('games.index', ['games' => $games]);
});
Once you are comfortable with creating Models and Controllers, you can even move on to
creating them at the same time if you like. For now, we are just going to pick a name for
our controller. So how do you name a controller? Well, we’ve been working with Games so
far. We have a game model, and a games table. Let’s name our controller
GamesController. We can created it by typing php artisan make:controller
GamesController.
The convention is to typically choose a word that describes what the controller will be
dealing with, having the first letter capitalized followed by the word “Controller” with a
capital C and no spaces or underscores.
Each route will point to a method on a controller. We have two routes, and one controller,
so that means we need to create two methods on our new controller. We will have one
named index to represent all games, and one called show to handle displaying one game
at a time. Here is the controller with those items stubbed out.
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class GamesController extends Controller
{
public function index()
{
}
}
We now want to move the logic from the routes file to the new controller.
The full GamesController will now look like the following. Note that since we are now
making use of the Eloquent Game Model we had created, we need to import that
using use App\Game; You’ll see that highlighted in this code snippet as well.
app/Http/Controllers/GamesController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Game;
Route::get('games', 'GamesController@index');
Route::get('games/{id}', 'GamesController@show');
This is now very simple, clean, and easy to understand. If a request is made to /games,
then Laravel knows to invoke the index method on the GamesController. If a request is
made to /games/{id}, then Laravel will invoke the show method of the GamesController.
Anything to the left of the @ sign is the controller. Anything to the right of the @ sign is the
method or function name in that particular controller.
What is Route Model Binding? I’m glad you asked! That is exactly what we’ll
take a look at in this post. So far we’ve been experimenting with various
features of the Laravel framework as we build out a simple application that
allows us to keep track of games in a database. We’ve created two routes so
far, and one of them accepts an id so that we can fetch a specific game from
our database. With route model binding we are going to make this step an
automated process. Let’s see how it works.
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Game;
Note that we have to pass in an $id of the game we are looking to find. In our routes file,
this route Route::get(‘games/{id}’, ‘GamesController@show’); makes use of that {id}
wildcard. So if someone types in /games/3 into the browser, the {id} is captured as the
number 3. That number is accepted into the show($id) method, and the game we want is
found using Game::find($id);
To this:
public function show(Game $id)
{
return view('games.show', ['game' => $id]);
}
We can remove this entire line of code $game = Game::find($id);, and simply place the
word Game in front of $id like so: show(Game $id). This is an example of making use of
something called Type Hinting. We are passing an $id, but we are hinting to the fact that
we want it to be an instance of a Game model. When we go back and test things out, it
looks like everything still works as before. Cool!
It’s important to note that the wildcard name in the routes file must exactly match the type
hinted variable passed to the function in the controller. In our
case /games/{id} corresponds to show(Game $id). If we had tried to do something
like show(Game $game) instead, the route model binding would not work.
By default, Laravel is making use of a primary key to find the record when using route
model binding. If you need to customize this to work instead with something like finding by
a slug, this is possible by customizing the key name in the Game model.
Note that we already have a games folder in the views directory. This holds our
current index.blade.php and show.blade.php files. Now that we have a layouts folder, we
can put a master template in there. By convention, it is usually
named master.blade.php so let’s create that file now and populate with some Bootstrap
boilerplate.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Games</title>
<link href="/css/bootstrap.min.css" rel="stylesheet">
<link href="/css/sticky-footer.css" rel="stylesheet">
</head>
<body>
<div class="container">
@yield('content')
</div>
<footer class="footer">
<div class="container">
<span class="text-muted">We Like Games</span>
</div>
</footer>
<script src="/js/jquery-3.1.1.slim.min.js"></script>
<script src="/js/tether.min.js"></script>
<script src="/js/bootstrap.min.js"></script>
</body>
</html>
<ul>
@foreach($games as $game)
<li><a href="/games/{{ $game->id }}">{{ $game->title }}</a></li>
@endforeach
</ul>
</body>
</html>
To this:
@extends('layouts.master')
@section('content')
<ul>
@foreach($games as $game)
<li><a href="/games/{{ $game->id }}">{{ $game->title }}</a></li>
@endforeach
</ul>
@endsection
Note that we have downloaded and installed a few files into the public folder. We have
placed bootstrap.min.css and sticky-footer.css in public/css as well as jquery-
3.1.1.slim.min.js, tether.min.js, and bootstrap.min.js in public/js. This approach is kind of
the poor mans way to assemble front end assets, but it’s good enough for this tutorial.
Extends
The next thing we did was to visit our index.blade.php file and remove the boilerplate. In
it’s place, we wrote out something like @extends(‘layouts.master’). This tells Laravel that
we want to make use of all the boilerplate now contained in master.blade.php, but we
don’t want to manually type it all out here. So in the index.blade.php file, we are now in
essence building upon what is contained in master.blade.php.
Section
Finally, we added a snippet to our index.blade.php file that began
with @section(‘content’) and then was subsequently rounded out with @endsection. This
defines an area of markup that is identified by the word ‘content’. Remember how in
our master.blade.php file, we have a part of the markup that uses the statement of
@yield(‘content’). Well now that we have a section defined in our index.blade.php file
which is identified as ‘content’, Laravel knows to grab that markup which exists
between @section(‘content’) and @endsection, and insert it right where
the @yield(‘content’) statement is.
</body>
</html>
To this:
@extends('layouts.master')
@section('content')
@endsection
In the show.blade.php file, we make use of bootstrap 4 cards which are new and look
pretty nice. We have also placed an image for each game in the public folder for a quick
and dirty example of how images look in bootstrap 4 cards. We simply use the title of each
game as the name of the image file. This way, we can set the src for the image to /{{
$game->title }}.png and everything works when we click on each game. Check it out!
resources/views/partials/headcontent.blade.php
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Games</title>
<link href="/css/bootstrap.min.css" rel="stylesheet">
<link href="/css/sticky-footer.css" rel="stylesheet">
</head>
resources/views/partials/navbar.blade.php
<nav class="navbar navbar-toggleable-md navbar-light bg-faded">
<button class="navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse"
data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-
expanded="false"
aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<a class="navbar-brand" href="#">We Like Games</a>
resources/views/partials/footercontent.blade.php
<footer class="footer">
<div class="container">
<span class="text-muted">We Like Games</span>
</div>
</footer>
<script src="/js/jquery-3.1.1.slim.min.js"></script>
<script src="/js/tether.min.js"></script>
<script src="/js/bootstrap.min.js"></script>
</body>
</html>
<body>
@include('partials.navbar')
<div class="container">
@yield('content')
</div>
@include('partials.footercontent')
In our little games app, we don’t yet have a way to add new games to the
database using the app itself. We are only able to insert new data by using the
MySql console directly, or via phpMyAdmin. Let’s change that up and start
looking at how we can add the ability to render a form so that we can submit
new games. We’ll need a new route and controller method to display the form,
as well as a new route and controller method to store the data into the
database. Let’s set this up now.
routes/web.php
<?php
Route::get('games', 'GamesController@index');
Route::get('games/{id}', 'GamesController@show');
Route::get('games/create', 'GamesController@create');
app/Http/Controllers/GamesController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Game;
Route::get('games', 'GamesController@index');
Route::get('games/create', 'GamesController@create');
Route::get('games/{id}', 'GamesController@show');
When we visit the route now, we get the nice text of ‘it works’ so we know the route and
controller method we want are working. With this sorted out, we can update
the create() method to render a view file for us so we can see the form.
public function create()
{
return view('games.create');
}
resources/views/games/create.blade.php
@extends('layouts.master')
@section('content')
<h2>Add a game</h2>
@endsection
Visiting http://54.dev/games/create shows us a pretty good looking form for submitting a
new game.
• The method attribute must be set to post: Every form is going to have an attribute
named method. This specifies the type of HTTP request you will make with the form.
When trying to add an item to the server, you must use a POST request. Since that
is exactly what we are trying to do, we set the method attribute to POST.
• The action attribute is set to /games: The other attribute that we must pay attention
to in forms is the action attribute. This tells us where do we want to send the post
request to. In keeping with convention, we make a post request to /games
• The enctype attribute is set to multipart/form-data: Since we are including the ability
to upload an image, we need to set the enctype attribute to multipart/form-data.
• csrf_field is required: To protect against cross site request forgery, you must include
this field just after the opening form tag like you see above. If this is not included, you
will run into token mismatch errors.
• each input has a unique name: Input tags in forms must have a name attribute with a
unique value set. This is how we identify which data corresponds to which input
when processing in Laravel or PHP on the server side.
• button type of submit: In order to submit the form, you’re going to need a button with
it’s type attribute set to submit!
Add post /games route and GamesController@store method
In order to actually process the data we enter into our form, we need the associated route
and controller method to do so. We can update our routes file like this.
<?php
Route::get('games', 'GamesController@index');
Route::get('games/create', 'GamesController@create');
Route::get('games/{id}', 'GamesController@show');
Route::post('games', 'GamesController@store');
Let’s go ahead and submit our form now to see what we get. Note that we did choose an
image, but it does not update visually in the form simply because that is beyond the scope
of this tutorial. The image will in fact be passed via the form however.
The result of dumping our request data looks like this.
This shows that we are definitely getting all the data we want. We can see all form fields
were successfully passed through the post request, including an image file which is an
object of type Illuminate\Http\UploadedFile. Fantastic.
We now want to be able to save the title, publisher, releasedate, and image path to the
database. In our current games table, we have fields for the title, publisher, and
releasedate, but nothing for the image path. Hmm. Looks like we might need to adjust our
migration file and re run the migrations. Let’s add this line to our original migration file.
<?php
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('games');
}
}
We are now going to run php artisan migrate:refresh, which will reset and re-run all
migrations. Don’t ever do this on a database for which you want to preserve data, because
this basically deletes everything and re builds the tables. All data will be lost. For our little
tutorial, this is no problem, but this is something to be aware of.
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Game;
$game->title = request('title');
$game->publisher = request('publisher');
$game->releasedate = request('releasedate');
$game->image = request()->file('image')->store('public/images');
$game->save();
}
}
What happens in this store() method is pretty straight forward. We are able to use
the request() helper function to access the data we want from the form. One of these kids
is doing his own thing however. Take a look at the line which has this: $game->image =
request()->file(‘image’)->store(‘public/images’); There are two things happening at once
here. Laravel is accepting the file from our form submission, and storing it in the
application at storage/app/public/images. At the same time, the path for the image is
stored in $game->image so we fetch the image source when we want to display it to the
browser later on. Let’s use tinker to see if everything is in the database like we expect.
Yes! It looks like it worked great, and we can see we now have an image path for the
uploaded file as well.
@section('content')
@endsection
@section('content')
@endsection
resources/views/games/create.blade.php
@extends('layouts.master')
@section('content')
<h2>Add a game</h2>
@endsection
Trying to submit a form that is not filled out properly now gives the user some feedback
about where they may have missed something or messed up.
app/Http/Controllers/GamesController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Game;
$game->title = request('title');
$game->publisher = request('publisher');
$game->releasedate = request('releasedate');
$game->image = request()->file('image')->store('public/images');
$game->save();
return redirect('/games');
}
}
With the highlighted code above, we now have some validation in place on the server side
as well. There are *a lot* of validation rules available to you, but we just want to make sure
each field is required. In addition to this, we want the title of the game to be unique. We
don’t want to add the same game to the database twice.
Displaying Errors If Needed
If the validation passes, the store() method just continues to go about it’s business of
inserting the provided data into the database. If there was a problem however,
an $errors variable will be populated and the user is re directed back to the form from
which they came. By reaching into that variable, we can display the errors to the user.
Here is how we might update our view file to handle this task.
resources/views/games/create.blade.php
@extends('layouts.master')
@section('content')
<h2>Add a game</h2>
@endsection
In one of our earlier posts, we had added The Legend of Zelda to the games table in our
database. Let’s try to add it again and see what happens.
Excellent! So even though we filled out all of the fields properly in the form, and got the
html5 client side browser validation to pass, we get a nice error message to tell us that the
title we provided has already been taken. So our validation rule we provided in
the store() method of our GamesController worked great. Recall we specified we want
a unique title by the rule of ‘title’ => ‘required|unique:games’.
resources/views/games/create.blade.php
@extends('layouts.master')
@section('content')
<h2>Add a game</h2>
@endsection
This is great now. We have redirected back to the form, yet the form data we originally
typed in is retained. You definitely want to handle things like this to improve the user
experience. Note that the old() function accepts an argument of the name of the field to
repopulate. In other words, whatever the value is that is set to the nameattribute for the
given input tag, should be the same value passed to the old()function.
Now in our create.blade.php file we just include it like so, and everything continues to work
as we would expect.
@extends('layouts.master')
@section('content')
<h2>Add a game</h2>
@endsection
With these steps in place, we have a decent little validation system going in our games
database app. Let’s finish off by adding one more game that we know meets all
requirements to be sure we are still able to add a new game to the database as we expect.
We fill out the details of our Metroid game to be submitted.
It looks like our addition is working great!
With these steps in place, we now have validation that makes sure users are entering the
right data to be submitted in our forms. If things are good, we add the data to the
database. If things do not meet the requirements we specified, then users are given a list
of errors to correct before trying again.
Let’s keep building out our simple games application with Laravel. In this tutorial
we will do a few things, in addition to adding the ability to add a review for any
given game. First off though, we’ll need to clean up the main games listing view
so it looks a little better. That may include tweaking the master layout page a bit
as well. We’ll take a moment to discuss how relationships work in Laravel,
create a new model and migration, update our models, and then test things out.
Let’s get started.
resources/views/games/index.blade.php
@extends('layouts.master')
@section('content')
@foreach($games as $game)
<div class="col-12 mb-3">
<div class="card">
<div class="card-block">
<h3 class="card-title"><a href="/games/{{ $game->id }}">{{ $game->title
}}</a></h3>
<p class="card-text">Published by {{ $game->publisher }}</p>
<a href="/games/{{ $game->id }}" class="btn btn-primary">Learn More</a>
</div>
</div>
</div>
@endforeach
@endsection
It turns out, if you’re using the navbar component in Bootstrap, you sometimes need to
manually add some padding to your container element in order to give some space to
breathe in the layout. We can update the master template file to accomplish this like so.
resources/views/layouts/master.blade.php
@include('partials.headcontent')
<body>
@include('partials.navbar')
@include('partials.footercontent')
With these two simple tweaks, our main games page looks a bit nicer.
This command created a new Review model for us, as well as a new migration. Let’s open
up that migration file and add a couple of fields to hold our review data. We are going to
add a body field of type string, and this is simply the field which will hold the text of a
review. Since we are now going to work with relationships between models as well, we are
going to add a game_id field to this reviews database table.
database/migrations/xxxx_xx_xxxxxx_create_reviews_table.php
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('reviews');
}
}
With our migration file updated for the new reviews table that we would like to add, we can
now migrate the database with php artisan migrate.
app/Game.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
We still have the cool little query scope we talked about in a prior tutorial, and we can
leave it right in place. We simply add our relationship right above in the reviews() method.
There is a convention at work here. It reads like, “This Game has many Reviews”.
belongsTo()
With our Game model updated to reflect that any game may have many reviews, we now
need to update or Review model. A given review will always be for a specific game. In
other words, a review will belong to a game. To represent that in our model, Laravel
provides the belongsTo() method. Again there is a convention in play. We can read this
relationship as, “This review belongs to a specific game”. So this is why we see that in the
belongsTo scenario, our method name is singular: game(). Let’s see how to implement
that right here.
app/Review.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
resources/views/games/show.blade.php
@extends('layouts.master')
@section('content')
<div class="card" style="width: 270px;margin: 5px">
<img class="card-img-top" src="{{ Storage::url($game->image) }}" alt="Card image cap">
<div class="card-block">
<h3 class="card-title">{{ $game->title }}</h3>
<p class="card-text">{{ $game->title }} is published by {{ $game->publisher }}</p>
<a href="/games" class="btn btn-primary">List Games</a>
</div>
</div>
<hr>
<div class="reviews">
<h4>What Gamers Are Saying</h4>
<ul class="list-group">
@foreach($game->reviews as $review)
<li class="list-group-item">{{ $review->body }}
<hr>
<small class="text-primary">posted {{$review->created_at-
>diffForHumans()}}</small>
</li>
@endforeach
</ul>
</div>
@endsection
Check it out!
The relationship methods are very convenient and make it easy to work with related
models. If we have an instance of a Game, we can easily fetch all associated reviews
with $game->reviews; Conversely, if we have an instance of a Review, we an easily see
which game it belongs to with $review->game; Very nice.
Add A Form To Add Game Reviews
Now that we have everything working in terms of fetching related models in our database,
then displaying them to the user, let’s go ahead and add a form to
our show.blade.php view so that we can add a new review for a game if we like and not
have to manually insert data with phpMyAdmin. First off, we’re going to need that form, so
here is a snippet to get us that.
resources/views/games/show.blade.php
@extends('layouts.master')
@section('content')
<div class="card" style="width: 270px;margin: 5px">
<img class="card-img-top" src="{{ Storage::url($game->image) }}" alt="Card image cap">
<div class="card-block">
<h3 class="card-title">{{ $game->title }}</h3>
<p class="card-text">{{ $game->title }} is published by {{ $game->publisher }}</p>
<a href="/games" class="btn btn-primary">List Games</a>
</div>
</div>
<hr>
<div class="reviews">
<h4>What Gamers Are Saying</h4>
<ul class="list-group">
@foreach($game->reviews as $review)
<li class="list-group-item">{{ $review->body }}
<hr>
<small class="text-primary">posted {{$review->created_at-
>diffForHumans()}}</small>
</li>
@endforeach
</ul>
</div>
<div class="addreview">
<div class="card-block">
<form method="POST" action="/games/{{ $game->id }}/reviews">
{{ csrf_field() }}
<div class="form-group">
<textarea name="body" class="form-control" placeholder="Add a
review!"></textarea>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary">Add a review!</button>
</div>
</form>
</div>
</div>
@endsection
app/Http/Controllers/ReviewsController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Game;
use App\Review;
return back();
}
}
Add a Route To the Routes file
With the ReviewsController setup along with our new store() method, we are going to
need the routes file to be updated as well. We can add a new route like so:
<?php
Route::get('games', 'GamesController@index');
Route::get('games/create', 'GamesController@create');
Route::get('games/{game}', 'GamesController@show');
Route::post('games', 'GamesController@store');
Route::post('games/{game}/reviews', 'ReviewsController@store');
namespace App;
use Illuminate\Database\Eloquent\Model;
app/Http/Controllers/ReviewsController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Game;
use App\Review;
Review::create([
'body' => request('body'),
'game_id' => $game->id
]);
return back();
}
}
This says that the body field must be filled out, and it also must be at least 3 characters
long. Let’s now include the partial in our add review form like so.
@extends('layouts.master')
@section('content')
<div class="card" style="width: 270px;margin: 5px">
<img class="card-img-top" src="{{ Storage::url($game->image) }}" alt="Card image cap">
<div class="card-block">
<h3 class="card-title">{{ $game->title }}</h3>
<p class="card-text">{{ $game->title }} is published by {{ $game->publisher }}</p>
<a href="/games" class="btn btn-primary">List Games</a>
</div>
</div>
<hr>
<div class="reviews">
<h4>What Gamers Are Saying</h4>
<ul class="list-group">
@foreach($game->reviews as $review)
<li class="list-group-item">{{ $review->body }}
<hr>
<small class="text-primary">posted {{$review->created_at-
>diffForHumans()}}</small>
</li>
@endforeach
</ul>
</div>
<div class="addreview">
<div class="card-block">
<form method="POST" action="/games/{{ $game->id }}/reviews">
{{ csrf_field() }}
<div class="form-group">
<textarea name="body" class="form-control" placeholder="Add a
review!"></textarea>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary">Add a review!</button>
</div>
@include('partials.formerrors')
</form>
</div>
</div>
@endsection
We can try adding a review that has less than 3 characters, and now that our store()
method and view are updated for validation, we get a nice error message lettings us know
what went wrong.
Refactor ReviewsController
The final thing we can take a look at is doing a small amount of refactoring in the
ReviewsController. Refactoring is the process of changing how the code is written, while
leaving the same functionality in place. The end result is the same, but the person reading
the code sees it differently. We do this in an attempt to make our code more readable and
easier to understand. It might be nice if in our store() method, we can make an adjustment
to the code to something like $game->addReview(request(‘body’)); It turns out, that is
something we can do. We just need to make a small update to our Game Model and
ReviewsController. We need to add a new method to Game Model of addReview() and we
need to update the store() method in our ReviwsController to make use of that new
method.
app/Game.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
With the addition of the addReview() method above, we can now call it in our
ReviewsController very easily. Check it out.
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Game;
use App\Review;
$game->addReview(request('body'));
return back();
}
}
Wow! Look at how nicely that store method reads now. We have an instance of a game,
and we add a review to it. Pretty nice. Does it work? Let’s see!
In this tutorial, we are going to hand build a user registration system in Laravel.
To be fair, we could actually make use of the php artisan make:auth command
to scaffold basic login and registration views and routes automatically for us.
This works great, but in the spirit of learning, we should know how to do this on
our own. By building an example of user registration and session management
from scratch, we will gain a much better idea of how to maintain and adjust
these features as we need to moving forward. Let’s go ahead and tackle user
registration and session management from scratch right now.
routes/web.php
<?php
Route::get('/games', 'GamesController@index');
Route::get('/games/create', 'GamesController@create');
Route::get('/games/{game}', 'GamesController@show');
Route::post('/games', 'GamesController@store');
Route::post('/games/{game}/reviews', 'ReviewsController@store');
Route::get('/register', 'RegistrationController@create');
Route::post('register', 'RegistrationController@store');
Route::get('/login', 'SessionsController@create');
Route::post('/login', 'SessionsController@store');
Route::get('/logout', 'SessionsController@destroy');
Here, we’ve broken the task of registering a user vs session related actions (sign in / sign
out) into their own controllers. The RegistrationController will handle offering a form to
register a new user, as well as a way to store a new user in the database once a form has
been filled out properly. The SessionsController is dedicated to handling offering a form to
sign in an existing user, signing them in if they fill out their credentials correctly, and also
logging them out when they like. You might be wondering why we use two controllers
when it seems it could all be handled in a dedicated AuthController of some type. The truth
is, that yes, you could easily do this in one controller. The reason here for two, is so that
we can more easily follow the RESTful method structure and be able to default to any of
the RESTful methods we might find for a resource. In other words,
index(), create(), store(), show(), edit(), update(), or destroy().
With regard to the routes we have laid out so far, we know that the create() method will
typically display a form to the user. From there they can fill it out and submit it. When they
submit it, they should send a POST request to a store() method. This method will either
create a new user in the case of RegistrationController, or sign in an existing user in the
case of SessionsController. Lastly, if an authenticated user visits the /logout route,
the destroy() method on the SessionsController will run and log them out of the session.
Makes perfect sense.
We’ll fist focus on adding the create() method which should display a form to the user so
he or she can fill out their information to sign up.
app/Http/Controllers/RegistrationController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
resources/views/registration/create.blade.php
@extends('layouts.master')
@section('content')
<h2>Register</h2>
<form method="POST" action="/register">
{{ csrf_field() }}
<div class="form-group">
<label for="name">Name:</label>
<input type="text" class="form-control" id="name" name="name">
</div>
<div class="form-group">
<label for="email">Email:</label>
<input type="email" class="form-control" id="email" name="email">
</div>
<div class="form-group">
<label for="password">Password:</label>
<input type="password" class="form-control" id="password" name="password">
</div>
<div class="form-group">
<button style="cursor:pointer" type="submit" class="btn btn-primary">Submit</button>
</div>
@include('partials.formerrors')
</form>
@endsection
If we visit the /register route, it looks like we do now have our form. Great!
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\User;
auth()->login($user);
return redirect()->to('/games');
}
}
app/User.php
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'name', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* @var array
*/
protected $hidden = [
'password', 'remember_token',
];
/**
* Add a mutator to ensure hashed passwords
*/
public function setPasswordAttribute($password)
{
$this->attributes['password'] = bcrypt($password);
}
}
We can now test out the new user form to make sure it is working. Let’s register Mario to
our games database.
If we look at the user in our database, we can see that Mario is in there! Note that his
password is properly hashed as well, no clear text. This tells us that our mutator on the
User model worked perfectly.
resources/views/partials/navbar.blade.php
In this snippet we use auth()->check() to see if the user is logged in. If this is true, then the
<li> tag is rendered and the user name is populated via auth()->user()->name. If this is
false, the <li> is not rendered at all. Perfect.
<nav class="navbar navbar-toggleable-md navbar-light bg-faded">
<button class="navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse"
data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-
expanded="false"
aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<a class="navbar-brand" href="#">We Like Games</a>
app/Http/Controllers/SessionsController.php
In our routes file, we already determined that there will be three methods on the
SessionsController. Those will be create() to offer a login form, store() to log an existing
user in, and destroy() to log a user out of the application. We can build those methods
now.
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
return redirect()->to('/games');
}
return redirect()->to('/games');
}
}
Create a Log In Form for the SessionsController@create() method
Just like the create() method in our RegistrationController offers a form to the user to
register to the site, so too will the create() method in our SessionsController offer the user
a form to Log In to the site. This form is a little more simple as it only needs to include
fields for an email and password. We’ll also include the partial we had created earlier for
displaying errors.
@extends('layouts.master')
@section('content')
<h2>Log In</h2>
<div class="form-group">
<label for="password">Password:</label>
<input type="password" class="form-control" id="password" name="password">
</div>
<div class="form-group">
<button style="cursor:pointer" type="submit" class="btn btn-primary">Login</button>
</div>
@include('partials.formerrors')
</form>
@endsection
Looking Good!
In the store() method of the SessionsController we can see we make use of the auth()-
>attempt(request([’email’, ‘password’]) method which returns false if the user fails to
log in, or true if the user logs in successfully. Knowing this, we can place this call in
an if statement. If the auth()->attempt() method is false, we return back to the form with
any errors. We use the back() and withErrors() functions to do this. Here we manually set
the message to: The email or password is incorrect, please try again. If the If the auth()-
>attempt() is true however, that means the user logged in successfully and we can now
redirect them to the /games route to view all games. We have a Mario user in the system,
but not a Luigi. Let’s try to log in as Luigi and see what happens.
The log in form is working good in the case of providing bad credentials. We are redirected
back to the form, and the errors show up nicely below the form. If we provide the correct
credentials for Mario, who is already in the database, we log in just fine.
Update Navigation to include Log In, Register, and Log Out links
The last method in our SessionsController is the destroy() method, and all it does is
call auth()->logout(); and then redirect the user to the /games route to view all games. In
order to make use of these routes, we should really add some navigation links to our
layout. We will need to account for what links to show based on whether a user is logged
in or not. In our navigation right now, we have a link to /games to view all games. We want
to show this for both logged in or logged out users. If a user is not yet logged in, we should
give them a link to both /login and /register. This way they can choose to log in if they
are an existing user, or create a new account by registering with the site if they like. If the
user is logged in, we will want to display their name, as well as give them a link
to /logout so they can log out if they like. Here is how we will do that in our navigation
area.
resources/views/partials/navbar.blade.php
<nav class="navbar navbar-toggleable-md navbar-light bg-faded">
<button class="navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse"
data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-
expanded="false"
aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<a class="navbar-brand" href="#">We Like Games</a>
Looks like our work is paying off. We visit the /register route via the new link we created
and we get the Registration form we expect. We then fill out some information, submit, and
voila, we have a new user created which immediately gets logged in. We can also see that
the navbar updates as we would expect based on if we are logged in or not. Finally, we
visit the /logout route via the Log Out link we provided, and we log right out. Awesome!
Let’s do a final check to make sure Mario, our first user, can still log in and out properly.
We can see that both users that we have registered to the site are able to log in and out
now with our user registration system. Excellent work!
resources/views/registration/create.blade.php
@extends('layouts.master')
@section('content')
<h2>Register</h2>
<form method="POST" action="/register">
{{ csrf_field() }}
<div class="form-group">
<label for="name">Name:</label>
<input type="text" class="form-control" id="name" name="name">
</div>
<div class="form-group">
<label for="email">Email:</label>
<input type="email" class="form-control" id="email" name="email">
</div>
<div class="form-group">
<label for="password">Password:</label>
<input type="password" class="form-control" id="password" name="password">
</div>
<div class="form-group">
<label for="password_confirmation">Password Confirmation:</label>
<input type="password" class="form-control" id="password_confirmation"
name="password_confirmation">
</div>
<div class="form-group">
<button style="cursor:pointer" type="submit" class="btn btn-primary">Submit</button>
</div>
@include('partials.formerrors')
</form>
@endsection
We now need to update the validation rules in the RegistrationController@store() method.
Very easy to do.
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\User;
return redirect()->to('/games');
}
}
We can try to register a new user, and intentionally mismatch the passwords, and the
validation works perfect for us.
When we first started out creating our little games app, we set up a form to add
games to the system. We also set up a form to add reviews for games in the
system. We were able to establish the relationships between games and
reviews. This was all done as a strictly guest based system as we had no user
authentication system until just recently. Now that we have a user registration
system in place, we need to find a way to associate users with both games and
reviews. A user could submit one or more games to the site. A user could also
submit one or more reviews to any given game. We can tackle the User to
Game and Review relationships in this tutorial.
Update Migrations
Right now we have a games table and a reviews table in the database which hold all the
information about, you guessed it, games and reviews! What is missing on those tables
are a way to link a particular record to a particular user. To facilitate this, we need
something like a user_id field on both of those tables. We can update those migrations
and refresh now.
database/migrations/xxxx_xx_xx_xxxxxx_create_games_table
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('games');
}
}
database/migrations/xxxx_xx_xx_xxxxxx_create_reviews_table
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('reviews');
}
}
Time to refresh the migrations. As we know, we will lose all games, reviews, and now
users out of our database when we do this. There are ways to set up a migration to alter a
MySql table instead of drop it and rebuild it, but we don’t really need to worry about that
here. So here goes nothing.
Update Models
In order to associate a User with a Game or Review, we need to update those models.
They are each going to need a new method to attach a Game submission to a user, and a
Review submission to a user. In other words, a game will belong to a user, and a review
will also belong to a user. We will use the belongsTo() relation for this. Here are those
updated models.
app/Game.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
app/Review.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
We can also update the User model as well. This is because a User can have many game
submissions, and may also have many review submissions. For this, we will use
the hasMany() relation.
app/User.php
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'name', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* @var array
*/
protected $hidden = [
'password', 'remember_token',
];
/**
* Add a mutator to ensure hashed passwords
*/
public function setPasswordAttribute($password)
{
$this->attributes['password'] = bcrypt($password);
}
Update Controllers
We are also going to need to update our controllers, and specifically we need to update
the store() methods on them. This is because before, when we were storing a game or
review in the database, we never accounted for the user that submitted the game or
review. We didn’t need to include that before, because any anonymous person could just
visit one of the forms, without any type of authentication in place, and submit a game or
review. Now that we have a user registration system in place, we want to track which
logged in user submitted which game or which review to the database. For this, we will
need to account for the user_id of the authenticated (logged in) user when
the store() method fires.
app/Http/Controllers/GamesController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Game;
$game->title = request('title');
$game->publisher = request('publisher');
$game->releasedate = request('releasedate');
$game->image = request()->file('image')->store('public/images');
$game->user_id = auth()->id();
$game->save();
return redirect('/games');
}
}
Notice above that we are now storing the id of the logged in user into the user_id field of
the games table before we save the model. We fetch the user id with auth()->id(). Very
good.
app/Http/Controllers/ReviewsController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Game;
use App\Review;
$game->addReview(request('body'), auth()->id());
return back();
}
}
This update to the store() method is a little more curious. Recall that we had extracted a
method to the Game model, and that is where we actually store the review using a relation.
When we call addReview() here in the ReviewsController, we were passing the body of the
add a review form via request(‘body’). We now also need to pass the user id as the
second parameter, and that is exactly what we did via auth()->id(). Of course this means
we must now also update the addReview() method on the Game model. Let’s go ahead
and do that now.
app/Game.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
Nice! Notice the addReview() method is now accepting that second argument, which is
then in turn passed as the second argument to the create() method as the second element
in the array. Now the create() method makes use of mass assignment, and recall that we
have already set body and game_id as fillable on the Review model. Well guess what, yes
that’s right, we must now also add the field of user_id to the fillable property on the Review
Model, otherwise this refactor above will fail when we go to add a review. We can update
the Review Model like so now.
app/Review.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
resources/views/partials/navbar.blade.php
<nav class="navbar navbar-toggleable-md navbar-light bg-faded">
<button class="navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse"
data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-
expanded="false"
aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<a class="navbar-brand" href="#">We Like Games</a>
resources/views/games/index.blade.php
@extends('layouts.master')
@section('content')
@foreach($games as $game)
<div class="col-12 mb-3">
<div class="card">
<div class="card-block">
<h3 class="card-title"><a href="/games/{{ $game->id }}">{{ $game->title
}}</a></h3>
<p class="card-text">Published by {{ $game->publisher }}</p>
<p class="small">Game submitted by user {{ $game->user->name }}</p>
<a href="/games/{{ $game->id }}" class="btn btn-primary">Learn More</a>
</div>
</div>
</div>
@endforeach
@endsection
Show the user name for a submitted game, and the user name for a submitted
review
We can now also update the resources/views/games/show.blade.php view to include the
name of the user that submitted the game being shown in addition to showing the name
associated with any reviews for that game. We can make use of $game->user->name to
show the user that submitted a game, and $review->user->name to show the user who
submitted a review. Here is how we can update the show.blade.php file to make this work.
resources/views/games/show.blade.php
@extends('layouts.master')
@section('content')
<div class="card" style="width: 270px;margin: 5px">
<img class="card-img-top" src="{{ Storage::url($game->image) }}" alt="Card image cap">
<div class="card-block">
<h3 class="card-title">{{ $game->title }}</h3>
<p class="card-text">{{ $game->title }} is published by {{ $game->publisher }}</p>
<p class="small">Game submitted by user {{ $game->user->name }}</p>
<a href="/games" class="btn btn-primary">List Games</a>
</div>
</div>
<hr>
<div class="reviews">
<h4>What Gamers Are Saying</h4>
<ul class="list-group">
@foreach($game->reviews as $review)
<li class="list-group-item">{{ $review->body }}
<hr>
<small class="text-primary">posted {{$review->created_at->diffForHumans()}} by
user {{ $review->user->name }}</small>
</li>
@endforeach
</ul>
</div>
<div class="addreview">
<div class="card-block">
<form method="POST" action="/games/{{ $game->id }}/reviews">
{{ csrf_field() }}
<div class="form-group">
<textarea name="body" class="form-control" placeholder="Add a
review!"></textarea>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary">Add a review!</button>
</div>
@include('partials.formerrors')
</form>
</div>
</div>
@endsection
Now we can log out, then log back in as “Mario” and also leave a review. At that point, we
should see that we are logged in as Mario, that the game was submitted by Toad, there is
one review by Luigi, and now we can add another review by Mario.
routes/web.php
<?php
//-- Games Resource --//
Route::get('/games', 'GamesController@index');
Route::get('/games/create', 'GamesController@create');
Route::post('/games', 'GamesController@store');
Route::get('/games/{game}', 'GamesController@show');
Route::post('/games/{game}/reviews', 'ReviewsController@store');
Route::get('/reviews/{review}', 'ReviewsController@show');
Route::get('/login', 'SessionsController@create');
Route::post('/login', 'SessionsController@store');
Route::get('/logout', 'SessionsController@destroy');
With our route in place, we can now define the index() method on the ReviewsController
as we see here. Now you may be wondering why we do not simply use $reviews =
Review::all(); to get all of the reviews to view. This is because it might be nice to display
the most recently added reviews. To do this, we can use $reviews = Review::latest()-
>get(); like we see.
app/Http/Controllers/ReviewsController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Game;
use App\Review;
$game->addReview(request('body'), auth()->id());
return redirect()->to('/games/' . request()->route()->game->id);
}
In the snippet above, it looks like we are loading an index.blade.php file from the reviews
directory. We do not yet have this, so let’s create that directory and file now. Do you see
the pattern here? We are looking at Reviews as their own resource, so we can dedicate a
views directory to it, then we can follow the convention of adding index.blade.php,
create.blade.php, and show.blade.php, just like we might with any other resource.
resources/views/reviews/index.blade.php
@extends('layouts.master')
@section('content')
@foreach($reviews as $review)
<div class="col-12 mb-3">
<div class="card">
<div class="card-block">
@endsection
There are a few things to notice here. We can see that we take the reviews and loop over
them in a foreach loop, just like we did when we were listing all games. Since we have set
up our eloquent relationships already, we can use $review->user->name to display the
user who submitted a review. We’d like to link to a particular review, so we do that by
setting the href attribute value to /reviews/{{$review->id}. We’ll set up the routes,
controller function, and view file to handle this in a bit. We can also link to the game a
review was left on by using the href value of /games/{{ $review->game->id }} and
fetching the game title as the anchor text using $review->game->title. Finally, we make
use of that convenient Carbon instance to show a human readable form of how long ago
the review was submitted with $review->created_at->diffForHumans().
Adding a List Reviews link to the Navigation
In the screenshot above we can see that we are now listing out all of the reviews in the
database. Each review shows the user that submitted it, the game it is associated with,
and a link to the review itself. We can also see a link in the navigation area similar to how
we have a link to view all games. Here is how we added that link.
resources/views/partials/navbar.blade.php
<nav class="navbar navbar-toggleable-md navbar-light bg-faded">
<button class="navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse"
data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-
expanded="false"
aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<a class="navbar-brand" href="/games">We Like Games</a>
routes/web.php
<?php
//-- Games Resource --//
Route::get('/games', 'GamesController@index');
Route::get('/games/create', 'GamesController@create');
Route::post('/games', 'GamesController@store');
Route::get('/games/{game}', 'GamesController@show');
Route::get('/reviews/{game}/create', 'ReviewsController@create');
Route::post('/games/{game}/reviews', 'ReviewsController@store');
Route::get('/reviews/{review}', 'ReviewsController@show');
Route::get('/login', 'SessionsController@create');
Route::post('/login', 'SessionsController@store');
Route::get('/logout', 'SessionsController@destroy');
Now check it out. With the Games resource, all we needed was a route of ‘/games/create’.
So why do we have that wildcard in the Reviews resource like this
‘/reviews/{game}/create’? This is because when we display a form, we are going to need to
display it for a specific game. We can use Route Model Binding to fetch the game that we
want to leave a review for, and display the form as such. With this in mind, we can now set
up the create() method on our ReviewsController and note how we again make use of
Route Model Binding which I have come to fall in love with.
app/Http/Controllers/ReviewsController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Game;
use App\Review;
$game->addReview(request('body'), auth()->id());
Let us now add a view to display a form. Since we have an instance of the game in
question, we are able to display in the form exactly which game we are leaving a review
for. This means we can remove the form from resources/views/games/show.blade.php and
replace it with a link to create a review for the given form like so: <a
href=”/reviews/{{$game->id}}/create”>Add A Review!</a>
resources/views/reviews/create.blade.php
@extends('layouts.master')
@section('content')
<h2>Add a Review for {{$game->title}}</h2>
<div class="addreview">
<div class="card-block">
<form method="POST" action="/games/{{ $game->id }}/reviews">
{{ csrf_field() }}
<div class="form-group">
<textarea name="body" class="form-control" placeholder="Add a
review!"></textarea>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary">Add a review!</button>
</div>
@include('partials.formerrors')
</form>
</div>
</div>
@endsection
We now have a dedicated route and view in place to render a form to submit a game
review.
app/Http/Controllers/ReviewsController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Game;
use App\Review;
$game->addReview(request('body'), auth()->id());
We should be good now. We should be able to visit a specific game, click the Add a
Review Link, fill out our review, submit, and then be redirected right back to that game so
we can see the game review we just submitted.
Customizing the sort order of an Eloquent Relationship
We can see that submitting reviews for a specific game is now working. Also note that
earlier, our new reviews were showing up last in the list of reviews. In the image above, we
show that new reviews are now being displayed first in the list. How do we do this? We did
this by extending the hasMany() relationship on the Game model. Here is how we do that.
app/Game.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
Route::get('/games/create', 'GamesController@create');
Route::post('/games', 'GamesController@store');
Route::get('/games/{game}', 'GamesController@show');
Route::get('/reviews/{game}/create', 'ReviewsController@create');
Route::post('/games/{game}/reviews', 'ReviewsController@store');
Route::get('/reviews/{review}', 'ReviewsController@show');
Route::get('/login', 'SessionsController@create');
Route::post('/login', 'SessionsController@store');
Route::get('/logout', 'SessionsController@destroy');
app/Http/Controllers/ReviewsController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Game;
use App\Review;
$game->addReview(request('body'), auth()->id());
resources/views/reviews/show.blade.php
@extends('layouts.master')
@section('content')
@endsection
resources/views/games/show.blade.php
@extends('layouts.master')
@section('content')
<div class="card" style="width: 270px;margin: 5px">
<img class="card-img-top" src="{{ Storage::url($game->image) }}" alt="Card image cap">
<div class="card-block">
<h3 class="card-title">{{ $game->title }}</h3>
<p class="card-text">{{ $game->title }} is published by {{ $game->publisher }}</p>
<p class="small">Game submitted by user {{ $game->user->name }}</p>
<a href="/games" class="btn btn-primary">List All Games</a>
</div>
</div>
<hr>
<div class="reviews">
<h4>What Gamers Are Saying</h4>
<ul class="list-group">
@foreach($game->reviews as $review)
<li class="list-group-item">{{ $review->body }}
<hr>
<a href="/reviews/{{$review->id}}"><small class="text-primary">posted {{$review-
>created_at->diffForHumans()}} by
user {{ $review->user->name }}</small></a>
</li>
@endforeach
</ul>
</div>
<div class="mb-3">
<h4 class="mt-3"><a href="/reviews/{{$game->id}}/create">Add A Review!</a></h4>
</div>
@endsection
Applying RESTful Methods to the Reviews Resource Summary
In this tutorial we gave the RESTful treatment to our Reviews resource. We can look at
game reviews as a first class citizen in our little application now, just like the Games
themselves. As we know, when adhering to the RESTful approach, we can choose from
the methods of index(), create(), store(), show(), edit(), update(), and destroy() to do our
work for us.
We don’t provide a link to /games/create for guests, but they could simply type it into the
browser, like we see above. We can use middleware to prevent them from being able to do
this. Since we want to protect something that has to do with a Games resource, we open
up the GamesController and apply our middleware like so:
app/Http/Controllers/GamesController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Game;
$game->title = request('title');
$game->publisher = request('publisher');
$game->releasedate = request('releasedate');
$game->image = request()->file('image')->store('public/images');
$game->user_id = auth()->id();
$game->save();
return redirect('/games');
}
}
Route [login] not defined.
If we now try to visit the /games/create route as a guest user, we see a problem.
routes/web.php
<?php
//-- Games Resource --//
Route::get('/games', 'GamesController@index');
Route::get('/games/create', 'GamesController@create');
Route::post('/games', 'GamesController@store');
Route::get('/games/{game}', 'GamesController@show');
Route::get('/reviews/{game}/create', 'ReviewsController@create');
Route::post('/games/{game}/reviews', 'ReviewsController@store');
Route::get('/reviews/{review}', 'ReviewsController@show');
Route::get('/login', 'SessionsController@create')->name('login');
Route::post('/login', 'SessionsController@store');
Route::get('/logout', 'SessionsController@destroy');
Once our route is named as ‘login’, if we then try to visit ‘games/create’ as a guest by
typing it into the browser, we will now in fact be redirected successfully to our login page.
Setting Up Middleware in the Constructor
An auth middleware is now in place on our Games Controller by way of setting it up in a
constructor function. What this means is that every single method in this controller is now
protected by the auth middleware. This means guest users can not even visit /games to list
all games or even visit a specific game such as visiting /games/3. They will be redirected
right to the login page if they try to do something like this. Do we really want that behavior
though? Maybe you do for your application, and if this is what you want, all you need to do
is add that $this->middleware(‘auth’); line to the constructor function, and your resources
will be locked down tighter than a banjo string.
app/Http/Controllers/GamesController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Game;
$game->title = request('title');
$game->publisher = request('publisher');
$game->releasedate = request('releasedate');
$game->image = request()->file('image')->store('public/images');
$game->user_id = auth()->id();
$game->save();
return redirect('/games');
}
}
This should allow us to view games and look at a specific game, but if we try to type in the
route to submit a new game as a guest, we’ll get redirected right back to the login page.
Let’s see this in action right here.
Can we fix this? Of course we can! All we need to do is to add the same type of auth
middleware to the Reviews Controller like we did with the Games Controller. We’ll also
make use of that except() method and pass an array of two strings, index and show, to
indicate that we want to protect all methods from guest users except for the index() and
show() methods. We can let guest users look at the list of reviews or look at a specific
review, no problem.
app/Http/Controllers/ReviewsController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Game;
use App\Review;
$game->addReview(request('body'), auth()->id());
With our update to the Reviews Controller and the addition of middleware in the
constructor function, as a guest we should now be able to list all reviews and also look at a
specific view, but if we try to visit the route to add a review – our new middleware should
say “oh no, you head over to the login page before you try adding a review”. Let’s see.
Whereas for our Games and Reviews Controllers we made use of the $this-
>middleware(‘auth’) middleware, when dealing with login and registration routes, we will
make use of the $this->middleware(‘guest’) middleware. The auth version is basically
stating, a user can only access this resource if he or she is authenticated. Quite the
opposite is the case for the guest middleware. It states that a user can only access
particular resources if they are a guest. Sounds great! Let’s go ahead and apply that guest
middleware to our Sessions Controller so that if a logged in user tries to visit the login
form, they will be redirected.
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
return redirect()->to('/games');
}
return redirect()->to('/games');
}
}
app/Http/Middleware/RedirectIfAuthenticated.php
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\Auth;
class RedirectIfAuthenticated
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @param string|null $guard
* @return mixed
*/
public function handle($request, Closure $next, $guard = null)
{
if (Auth::guard($guard)->check()) {
return redirect('/games');
}
return $next($request);
}
}
With that small change, if we try to type in the url of our login form at /login as an
authenticated user, we get redirected right to the /games page. This is the exact behavior
we were looking for.
It looks like that is the case. We can now add our guest middleware to the
RegistrationController to fix this.
app/Http/Controllers/RegistrationController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\User;
auth()->login($user);
return redirect()->to('/games');
}
}
In this installment of our games app, we are going to add a sidebar for the main
games and reviews views. In other words, when the site user is listing all
games to view or all reviews to see, there will be a sidebar displayed. This
sidebar will hold information about the games and reviews that have been
submitted by users of the site. Specifically, we would like to show the user who
has submitted the most games first, the user who has submitted the second
most games second, and so on. It’s a way to feature so to speak, the active
contributors to the site. How can we do this? We are going to do this by making
use of raw sql queries combined with Eloquent. Let’s see how to do this now.
Ok what happened there? We now get the result of Mario, Mario, Mario, Toad, Luigi, and
Toad. Not really what we need just yet. We need to somehow count the number of games
each user submitted. For this, we are going to need to make use of the aggregate
function count() and the GROUP BY clause. Here, we must specify a count of all games
submitted and rename the temporary table as an alias of submitted_games. With that
complete, we would need to group those results by the user’s names. Let’s see:
We’re getting close! Now we can see that Luigi has submitted 1 game, Mario has
submitted 3 games, and Toad has submitted 2 games. We want to highlight the most
active game submitters however, so we want Mario at the top and Luigi at the bottom. We
can just add a handy ORDER BY clause to get this done. What will we order by? We shall
order by the number of submitted games in descending order.
This is exactly what we want, and taking this small incremental approach to building up
database queries is helpful. We now know what we are trying to do, and how to do it with a
raw query. Let’s get this into Laravel now.
app/Http/Controllers/GamesController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Game;
use App\User;
$game->title = request('title');
$game->publisher = request('publisher');
$game->releasedate = request('releasedate');
$game->image = request()->file('image')->store('public/images');
$game->user_id = auth()->id();
$game->save();
return redirect('/games');
}
}
resources/views/games/index.blade.php
@extends('layouts.master')
@section('content')
<div class="row">
<div class="col-8">
@foreach($games as $game)
<div class="mb-3">
<div class="card">
<div class="card-block">
<h3 class="card-title"><a href="/games/{{ $game->id }}">{{ $game->title
}}</a></h3>
<p class="card-text">Published by {{ $game->publisher }}</p>
<p class="small">Game submitted by
user {{ $game->user->name }} {{ $game->created_at->diffForHumans()
}}</p>
<a href="/games/{{ $game->id }}" class="btn btn-primary">Learn More</a>
</div>
</div>
</div>
@endforeach
</div>
<div class="col-4">
@include('partials.activeusers')
</div>
</div>
@endsection
resources/views/partials/activeusers.blade.php
The markup for the partial view file.
<table class="table table-sm table-hover">
<thead class="thead">
<tr>
<th>User Name</th>
<th>Games Submitted</th>
</tr>
</thead>
<tbody>
@foreach($activeusers as $activeuser)
<tr>
<td>{{ $activeuser->name }}</td>
<td>{{ $activeuser->submitted_games }}</td>
</tr>
@endforeach
</tbody>
</table>
Looking Good!
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Game;
use App\Review;
use App\User;
$game->addReview(request('body'), auth()->id());
@section('content')
<div class="row">
<div class="col-8">
@foreach($reviews as $review)
<div class="col-12 mb-3">
<div class="card">
<div class="card-block">
@endsection
We now have the most active users displaying on both the /reviews and /games endpoints.
Refactor Time
Those queries in our controller methods are not the best looking. We must fix this with
vigor and tenacity at once. Let us extract this functionality elsewhere, where it can hide it’s
complexity in the shadows.
First we will write out the code, as we would like to have it in the controller. It would be nice
if we could simply fetch our active game submitters with something as simple
as $activeusers = User::activeusers(); In fact, we will update the Games Controller as such
right now.
app/Http/Controllers/GamesController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Game;
use App\User;
$activeusers = User::activeusers();
return redirect('/games');
}
}
app/User.php
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'name', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* @var array
*/
protected $hidden = [
'password', 'remember_token',
];
/**
* Add a mutator to ensure hashed passwords
*/
public function setPasswordAttribute($password)
{
$this->attributes['password'] = bcrypt($password);
}
app/Http/Controllers/ReviewsController.php
We can now make our Reviews Controller pretty as well.
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Game;
use App\Review;
use App\User;
$activeusers = User::activeusers();
$game->addReview(request('body'), auth()->id());
resources/views/games/show.blade.php
@extends('layouts.master')
@section('content')
<div class="row">
<div class="col-8">
<div class="card" style="width: 270px;margin: 5px">
<img class="card-img-top" src="{{ Storage::url($game->image) }}" alt="Card image
cap">
<div class="card-block">
<h3 class="card-title">{{ $game->title }}</h3>
<p class="card-text">{{ $game->title }} is published by {{ $game->publisher
}}</p>
<p class="small">Game submitted by user {{ $game->user->name }}</p>
<a href="/games" class="btn btn-primary">List All Games</a>
</div>
</div>
</div>
<div class="col-4">
@include('partials.activeusers')
</div>
</div>
<hr>
<div class="reviews">
<h4>What Gamers Are Saying</h4>
<ul class="list-group">
@foreach($game->reviews as $review)
<li class="list-group-item">{{ $review->body }}
<hr>
<a href="/reviews/{{$review->id}}">
<small class="text-primary">posted {{$review->created_at->diffForHumans()}}
by
user {{ $review->user->name }}</small>
</a>
</li>
@endforeach
</ul>
</div>
<div class="mb-3">
<h4 class="mt-3"><a href="/reviews/{{$game->id}}/create">Add A Review!</a></h4>
</div>
@endsection
We visit in our Browser, and what?! Undefined variable: activeusers (View:
/home/vagrant/Code/54/resources/views/partials/activeusers.blade.php
Dang Nabbit!!! So we recall, oh yeah that’s right, we need to use that custom query we had
put together and make a call to the database so we can populate the $activeusers variable
and send it on over to our view file so we stop getting these errors. Ok! Let’s go ahead and
update the show() method of our Games Controller.
app/Http/Controllers/GamesController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Game;
use App\User;
$activeusers = User::activeusers();
$game->title = request('title');
$game->publisher = request('publisher');
$game->releasedate = request('releasedate');
$game->image = request()->file('image')->store('public/images');
$game->user_id = auth()->id();
$game->save();
return redirect('/games');
}
}
Now we look good!
Fantastic! You see how to include this partial view file anywhere in the app if you like.
Tutorial over… Just kidding! Here in lies the problem. We just fixed the issue, but what did
we have to do? Think about back to when we first created the most active users widget. At
first, we were just going to display this widget in the index view of the Games resource. So
easy enough, we included the partial in that view file and updated the index() method of
the Games Controller. Then, we thought about it, and said gee “It might be nice to add this
widget to the Reviews index view as well”. So we go ahead and include the partial in that
view file, then update (read: duplicate) the logic from our Games index() method to our
Reviews index() method. Finally in this tutorial, we think, hmm, why don’t we go ahead and
add that cool little widget to the show view file for Games. So we add our partial view file to
include this widget then test it out in the browser and it grenades. Here is the problem: Any
time we want to make use of that partial view file in our app, we have to track down the
Controller and method responsible, and keep duplicating the same query over and over,
just to make sure one particular variable is populated. There is a better way.
app/Providers/AppServiceProvider.php
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use App\User;
/**
* Register any application services.
*
* @return void
*/
public function register()
{
//
}
}
What this code here does is to set up a listener of sorts that listens for any time the
partials.activeusers view file gets loaded in our application. We can see that the second
parameter to the composer() method is a callback function. This function gets triggered
any time the partials.activeusers view file is loaded. So inside this callback function, we
can go ahead and populate that $activeusers variable. With this logic in place, our
application could load the partials.activeusers view file in one Controller method, or all of
them if you like. No matter what, that partial will be getting access to the data it needs
every time. In our case, that is the populated $activeusers variable. So go ahead and
update any controller method that is still making calls to $activeusers = User::activeusers();
and remove it. You can also remove the passing of the $activeusers variable to the view
files. Our view composer takes care of all of this automatically now.
Everything is working perfect. Our little widget displays without issue on any part of our
website that calls for it. We could add it everywhere if we like, and that view composer
would still have our back.
What is a View Composer in Laravel Summary
View composers are one of those magical little tricks in Laravel that help to make things
just a little bit easier. Could you get by without them? Sure, but once you get the hang of
how to use them, you will find that they make perfect sense in many scenarios.
class Chore {
public $description;
}
A Class Can Have Properties
This little snippet just tells us that our Chore is going to have a description. So what is the
deal with that word public? That deals with something we call encapsulation, and we’ll
review that when we’re ready. For now, all we need to know is that our class has a
description property. Since we have a description for a chore, let’s go ahead and hard
code a value into that description. What’s a good description for a chore? How about,
‘Clean the dishes’.
class Chore {
public $description = 'Clean the dishes';
}
Now if we have a class like this with a description and a value within it, how the heck do
we make use of that information? How can we access it? The answer is to create a new
instance of the class. A new instance of the class is referred to as an object. Once we
have an object, we can make use of any properties inside it. This is how we might do that.
$chore = new Chore;
echo $chore->description;
The $chore variable now actually holds an instance of, or object, of the class Chore. Great!
Since we have that instance, we can now access the properties within it.
Now check it out. Our class is akin to a blueprint, but there is a value hard coded into our
description. Does that make sense? Does a blueprint for a house contain the color of it’s
siding? Probably not. One house might have blue siding, while another might have red. It
makes sense then that our description should have a way to be able to decide what value
it will have. In addition, think about what would happen if we instantiate, or New Up a
bunch of objects or instances of our Chore class. Are we going to have 10 chores where
all of them are to ‘Clean the dishes’? Of course not. We need a way to set the description
for all of the various objects that we are going to create. A great way to assign a value to a
property as soon as the object is created is by use of a constructor. Let’s see what that
looks like.
<?php
class Chore {
public $description;
This is a nice way to create three Chores and they each have a unique description. As it
stands now, this code will not work. We need to update our class code, so that when we
new up an instance of that class, it will be able to accept a value and assign it to the
description property. This is how we can do that very thing by making use of the
constructor.
Notice that the constructor now has an argument. That is the $description that you see
between the ( and the ). This represents the text that we provide when we new up
an object, or a new instance of the Chore class. This text then gets assigned to the
description property of that instance by way of $this->description. At this point, we are
making use of $this, which has brought many a headache, confusion, and gnashing of
teeth to the beginning object oriented programmer. When we use $this, we are making
use of a way to distinguish between multiple instances of the same class. Just up above
we created three instances of the Chore class right in a row. It is by the use of $this, that
the assignment of the description value is handled correctly to each of the three objects.
We can prove this by accessing the value of each description property on each object like
so:
echo $chore1->description;
// Paint the shed
echo $chore2->description;
// Clean the garage
echo $chore3->description;
// Mow the grass
Here we can see that we currently have three Chores, and they all have a unique
description property.
class Chore {
public $description;
$chore1->complete();
echo 'It is '.var_export($chore1->completed). ' that I have finished the first chore.';
The resulting sentence reads, “Right now, I need to Paint the shed. It is true that I have
finished the first chore.” Since we made a call to the complete() method, the description
property was changed from false to true. So now, we have a way to maintain the status of
a chore and where it is completed or not.
class Motorcycle {
Assuming we have a motorcycle, this motorcycle will have come from a manufacturer. In
fact, every single motorcycle has a manufacturer so let’s set up a way to make sure our
motorcycle objects have a manufacturer from the get go. We can use our handy magical
constructor function to allow for that.
<?php
class Motorcycle {
public $make;
echo $motorcycle->make;
// Harley
This code above here represents the day you convinced your wife to allow you to purchase
a brand new Harley Davidson. Cool. Now being the tinkerer that you are, you figure you
want to be able to customize your new Harley. Maybe you have an obsession with tires,
and you want the ability to easily change them based on weather conditions. Sounds
great, let’s add that ability now.
<?php
class Motorcycle {
public $make;
public $tires;
$motorcycle->tires = 'Dunlop';
echo $motorcycle->tires;
// Dunlop
Awesome! That was pretty easy. What if you decide you want to change out your Dunlop
tires for a set of Pirelli tires because you heard they are better in the summer. That’s easy
to update.
<?php
class Motorcycle {
public $make;
public $tires;
$motorcycle->tires = 'Pirelli';
echo $motorcycle->tires;
// Pirelli
Now you may be thinking, “We’re both assigning and retrieving values from our property,
and we haven’t even talked about these silly getters and setters. What gives?” That’s a
valid thought actually. There is a good reason for them though, and we’ll explore it now.
class Motorcycle {
public $make;
public $tires;
$motorcycle->tires = 'Cooper';
echo $motorcycle->tires;
// Cooper
Boom. Just like that, you go from hero to zero on the track. We need a way to prevent
RacerX from tampering with your machine again.
class Motorcycle {
public $make;
public $tires;
$motorcycle->setTires('Cooper');
echo $motorcycle->tires;
// Exception: Oh hell no!
At this point, RacerX is going to try and use our new method setTires to maliciously install
a set of poorly performing Cooper tires on our race ready Harley. Take note however of the
logic we placed inside our method. Before we assign the tires property, we do a quick
check on it’s value. We set up a rule such that if the tires are Cooper, we will throw an
exception and not allow those tires to be installed. It turns out, this is the only way we can
implement this type of security or behavior to the act of setting a value to our property.
When we work with properties directly, there is no way to hook in to this behavior, which is
why getters and setters are a good thing.
Since we have shown how to use a setter, let’s also review how to use a getter. It’s pretty
easy, we simply do it like so:
<?php
class Motorcycle {
public $make;
public $tires;
$motorcycle->setTires('Firestone');
echo $motorcycle->getTires();
// Firestone
We have not yet added any behavior to our getter method. It would seem that there would
be no reason to since all we are doing is returning a value, but if you think about it, maybe
you want to apply some type of formatting to your data. In this case, let’s imagine that the
sanctioning agency wants to check the tires of all racers, and they only accept the brand of
tire in all uppercase letters. We can implement that with our getter like so.
public function getTires() {
return strtoupper($this->tires);
}
We simply wrap our return statement with a call to strtoupper and we are in business.
Note:It is a common convention to use camel case for getter and setter methods. That
means the get or set portion of the method name is lowercase, followed by the property we
are getting or setting with the first letter capitalized. By using this approach, consumers of
our class are forced to abide by the logic we set in our hooks. In addition to this approach,
PHP also has a built in way of dealing with getters and setters via the magical
method special functions __get() and __set().
public $tires;
$motorcycle->tires = 'Cooper';
echo $motorcycle->getTires();
// COOPER
Ut oh. Do you see that right there? Our Harley is now sporting a pair of wretched rubber
that will lead to bad results in our upcoming race. How did that happen? Well, here is
where encapsulation comes in. RacerX was able to continue to access our property
directly, because we left it’s access modifier set to public. WTF? What is an access
modifier!? Let’s investigate.
• Public Access Modifier
Public is the least restrictive as it says that anyone or any class can access the
property or method.
• Protected Access Modifier
Protected is a little bit more secure. It says that only the current class and any child
or subclasses of the class will have access to the field or method.
• Private Access Modifier
Finally we have Private which is the most secure and offers only the current class to
have access to the field or method.
Now that we have a little bit in the way of definitions for the public, protected, and private
access modifiers, let’s apply them to our code and see what happens. First, we’ll move to
a protected instance of tires, and test things out.
In our source code we change
public $tires
to
protected $tires
Then the malicious competitor comes along and tries to change our tires by directly
accessing our property like so
$motorcycle->tires = 'Cooper';
However, we have protected ourselves! PHP now throws an exception to this!
// Fatal error: Cannot access protected property Motorcycle::$tires
Our racer enemy is not quick to give up however. He decides that he’ll simply try to apply
those Cooper tires to our trusty Harley by using the setTires setter method that we have
configured for our class. Recall though that he will fail miserably as we have built in some
logic to ensure this can not happen!
$motorcycle->setTires('Cooper');
// Exception: Oh hell no!
Currently we have Dunlop tires on our Harley. The word on the street however is that
Bridgestone tires are the hot new thing and we want to be able to test them out for
ourselves. Will we be able to change our tires to Bridgestone successfully?
$motorcycle->setTires('Bridgestone');
echo $motorcycle->getTires();
// BRIDGESTONE
In fact yes, yes we can. By making use of Encapsulation along with good use of getters
and setters, we have successfully built a class that is able to blacklist certain types of tires
from being mounted on our rims. We can still however mount the better performing tires
anytime we want, since we allow for that in the logic of our setter.
Let us now create a child class of our Motorcycle class, and try setting and getting the tires
of the child. We will create a Minicycle class that extends the Motorcycle class.
class Minicycle extends Motorcycle {}
$minicycle->setTires('Cooper');
// Exception: Oh hell no!
Since the Minicycle class inherits from the Motorcycle class, it too will be able to prevent
attempts of people to install Cooper tires on it’s rims as well.
class Minicycle extends Motorcycle {}
$minicycle->setTires('Dunlop');
echo $minicycle->getTires();
// DUNLOP
Mounting a set of tires from our approved selection of brands does work fine however.
Creating A Black Box
One of the biggest selling points of object oriented programming is the idea of a black box.
When we say black box, what we mean is that as a consumer of a given class, we don’t
care how it completes it’s job, just as long as it does the job accurately and successfully. In
this example of using getters and setters to change tires on a motorcycle, we have so far
kept it very simple. In real life however, there are probably many steps to actually change a
tire. For example, we’d need to let the air out of the old tires. Then we might need to
wrestle with a tire iron to pry the tire off of the rim. After that we’d have to do the same
thing to try and pry a new tire onto the rim, and finally we would have to inflate the new
tires once we were able to get them back on the rims. There are likely even more steps
than that. Consider the team owner. He doesn’t care about all the steps it takes to change
a tire. He just knows that Bridgestones are the hot new thing, so he says to the mechanic,
“Change the tires”. The team owner want to be able to simply give the order, and when he
comes back from getting a burger at the concession stand, the hot new Bridgestones will
be mounted. This is kind of how the idea of a Black Box works. Another example might be
your manager at work. Maybe you deal with clients that are having technical problems and
your manager wants you to “fix the client” or “make them go away”. Well in order to fix the
client, or make them go away, it may take ten different procedural actions to take in a very
specific order, and possibly some prayers. The boss doesn’t care how you get it done. Just
get it done. Use the tools and knowledge in your head (these are the private methods and
properties) and fix the client.
Let’s create this idea in code for our Motorcycle class.
<?php
class Motorcycle {
public $make;
protected $tires;
In this snippet above we add two new private methods. These methods are meant to be
used exclusively and only by the Class itself. Objects of this class can not make use of
them, nor can child or sub classes, or anyone else for that matter. These private methods
contain the special and secret steps to complete a specific job. In this case, we are simply
hiding the implementation of successfully changing tires on a motorcycle. When we need
to change tires, we simply do so via our setTires() method and things still work perfect. We
don’t care how it gets done, just as long as it gets done.
$motorcycle = new Motorcycle('Harley');
$motorcycle->setTires('Dunlop');
echo $motorcycle->getTires();
// DUNLOP
As we can see above, our ability to mount the right tires still works like a champ. Let’s think
about that RacerX frenemy we have however who might be interested in doing something
malicious to our motorcycle to gain an advantage. Maybe he thinks secretly removing all
the air from our tires will be his key to a victory. Let’s see what happens when someone
tries to call our deflateOldTires() method in a malicious way.
$motorcycle = new Motorcycle('Harley');
$motorcycle->setTires('Dunlop');
$motorcycle->deflateOldTires();
// Fatal error: Call to private method Motorcycle::deflateOldTires()
Boo Yeah!You see, no one can peer into our black box! Because this method is private, only
the class itself can make use of it to accomplish the overall goal of the public interface of
that class.
class Father
{
public function getGender()
{
return 'Male';
}
}
As we can see in the example, when we new up, or instantiate a Son object, we are able to
make use of the getGender() method. If you look in the Son class however, it is a blank
slate with nothing in there. How are we able to make use of that method? We can make
use of the getGender() method because of Inheritance. Specifically, the Son class inherits
from the Father class. This is exactly why we use inheritance. We use it for when we want
to inherit behavior from a parent class. Of course since people love jargon so much,
the parent class could also be referred to as the base class or super class. The child
class goes by things such as the derived class, the sub class, or the heir class. They all
mean the same thing.
You now get access to all of the methods found at this link, and it’s a lot of them! So by
writing about two lines of code, you get to access hundreds of extremely helpful methods.
Sounds like a good deal, right? That is exactly what inheritance is for.
class Vehicle {
public function getWheels()
{
}
}
class Car extends Vehicle {
Hmm… Notice a problem there? We want to make use of inheritance to make fetching the
number of wheels from any of our Vehicles easier. The problem is, the algorithm to fetch
the number of wheels for a Car versus a Unicycle is different. So it would seem that we
can’t place just one method in the parent class and expect all the sub classes to be able to
use it successfully in this case. How can we overcome this?
Shared Behavior Design
By looking at our collection of vehicles, we can see that a Motorcycle and a Segwaycould
probably make use of the same algorithm. This is to say, both of them have two wheels.
So if we have a case where the same algorithm can solve a problem for more than one
type of sub class, then we can put that common behavior in the parent class. Let’s take
care of that now.
<?php
class Vehicle {
public function getWheels()
{
return 'Two Wheels';
}
}
Method Overriding
The prior example is a good solution to sharing behavior, but it also introduces a problem.
Our Car class currently extends the Vehicle class. The Vehicle class has a dedicated
method for fetching the number of wheels of our Vehicle. Let’s try out the method on an
instance of the Car class.
echo (new Car)->getWheels();
// Two Wheels
Whoops. It looks like our software has a bug. We called the getWheels() method on
our Car class and it returned a value of Two Wheels. Cars don’t have Two Wheels, they
have Four. In this case, we need to provide the Car class with it’s own implementation of
the getWheels() method, and we can do this by replacing or overriding the method of the
parent class. We’ll just make one small change to our Car class to get it working correctly.
<?php
class Vehicle {
public function getWheels()
{
return 'Two Wheels';
}
}
Now, even though the Car class inherits from the Vehicle class, it is able to return the
correct number of wheels for a Car since it has it’s own implementation of
the getWheels() method. Any time you need a unique behavior for a sub class, you can
easily override methods of the parent class.
What If All Sub Classes Are Unique?
Let’s imagine that we only have a Car, Motorcycle, and a Unicycle. We still have our
Vehicle class that we want to extend from. Is there anything to be gained from trying to
implement a shared behavior in the parent class at this point? There is no shared behavior
any more, so probably not. We no longer have a shared behavior, but it would still be nice
to be able to fetch the number of wheels from our three different types of Vehicles. There
are two reasons why a Vehicle parent class might still be useful.
• 1. Will there be any attributes that could be shared across every Vehicle? If so, put
this in the parent class to prevent having to write the same thing multiple times in the
sub classes.
• 2. Do you still want the ability to implement a specific behavior on all sub classes,
even if each implementation is different? If so, you can force this by way of a contract
in an abstract class with the template method design pattern.
Let’s add these two ideas to our abstract parent Vehicle class.
<?php
What this code does is implement the ability to both set a color, and retrieve the color of
any sub class that extends from Vehicle. This way, you only need to write the code in the
constructor and set up a getter once, in the parent class. You will not need to write this
over and over in the sub classes. We also have implemented an abstract protected
method which forces sub classes to declare their own implementation of
a getWheels() method. This is kind of similar to how an interface works. If we try to make a
class that extends from Vehicle and we don’t include a getWheels() method, an exception
will be thrown. Let’s see.
<?php
class Country
{
class Player
{
class Team
{
Excellent. Now of course, these classes are empty so we’re not going to be exactly tearing
up the FIFA circuit, but let’s see if we can change that. Let’s think about the Country.
A Country is going to need a name, like the USA, and it will depend on a Team, in order to
be a candidate for the FIFA world cup. Let’s add those items in now.
class Country
{
protected $team;
protected $name;
What we do here is pass two arguments to our constructor. The first is the dependency,
which makes use of Type Hinting. We prefix the variable with the type of object we wish
to depend on. This is our first instance of Dependency Injection and it comes in the form
of Constructor Injection. The second argument is simply the nameof the Country, which
will default to USA if none is provided. Ok, we have a Countrythat depends on a Team, but
our current Team class is empty so it will not be of much benefit. Let’s add some meat to
our Team. What does a Team need? It needs some players. How does it get players?
Well, they would need to join the team. We could also say we depend upon a player to
join the team. Let’s code this up.
<?php
class Team
{
protected $players = [];
First off we create a players array to hold all of our players. When we new up a Team, we
will automatically generate a players array to hold the players that join the team. There’s a
keyword there, join. A Player will need to join the team. We create the joinmethod and
pass in a Player object. We again use type hinting here to indicate we expect an object of
type Player. This is our second instance of Dependency Injection, but this time we are
using Method Injection. Finally, we just create a simple getter method of getplayers() so
we can see who is on our team as we add players. The Player class should be easy as all
we have to do is give our player a name.
<?php
class Player
{
protected $name;
Sending Messages
<?php
class Country
{
protected $team;
protected $name;
Now our Country has the ability to recruit new players for their Team. Note that this is an
example of message passing. The name of the method and its input parameters are
conceptualized as a message. We’re about ready to test this out. Now we now that
a Country is going to Depend On a Team. In other words, when we new up a Country, we
need to pass in a Team object. So first, we will create a Team object, then we will create
a Country object, and pass in that instance of the Team.
$team = new Team;
Perfect. Now we need to recruit some players to our Team. In order to recruit a player,
they must first exist. Let’s create a new Player now.
$player1 = new Player('Carli Lloyd');
Let’s now confirm who is on our Team. Remember, we created a getplayers() getter on
our Team class to do just that for us.
$team->getplayers();
Array
(
[0] => Player Object
(
[name:protected] => Carli Lloyd
)
)
Awesome!We can see that we have one Player object with the name of Carli Lloyd on our
team. We’re going to need much more than one player to be successful, so let’s add a
bunch of teammates.
$player2 = new Player('Morgan Brian');
$player3 = new Player('Ashlyn Harris');
$player4 = new Player('Tobin Heath');
$player5 = new Player('Alex Morgan');
$usa->recruit($player2);
$usa->recruit($player3);
$usa->recruit($player4);
$usa->recruit($player5);
Array
(
[0] => Player Object
(
[name:protected] => Carli Lloyd
)
Now that’s a Team! We have some fantastic players such as Morgan Brian, Ashlyn Harris,
Tobin Heath, Alex Morgan, and Carli Lloyd.
What Is An Interface?
An interface is an outline of what a particular object can do. You will often hear that an
interface is a contract. This is true in as much as an interface defines the public
methods that a class must implement. For example, if you have two objects that are each
instances of a different class, yet they implement the same interface, then both objects
must at a minimum offer the public methods defined in the interface which they implement.
An interface contains no logic. In addition to this, interfaces contain no data variables, only
function prototypes.
Interface Syntax
When looking at the code, an interface almost looks like a class definition. Instead of using
the class keyword however, we simply use the interface keyword when coding. In
addition, the methods we define in the interface will have no curly braces {}, as there is no
logic. Let’s see an example of an interface.
<?php
interface Lawnmower {
public function cut_grass();
}
Implementing an Interface
We implement an interface to enforce behavior. Consider that you are shopping for a new
Lawnmower. You have narrowed it down to three models. One from Kubota, one from
John Deere, and one from CrappyMowersInc. Two of these implement
the Lawnmower interface, that is to say they are guaranteed to be able to cut_grass(). The
third does not implement the Lawnmower interface. Let’s go lawnmower shopping in our
code.
<?php
interface Lawnmower {
public function cut_grass();
}
As we see here, the two models that implement the correct interface are the ones we like.
In addition, since both of the classes we like implement our Lawnmower interface, they are
essentially interchangeable. So it doesn’t really make a huge difference if you go with
the Kubota or the JohnDeere, they will both cut your grass just fine.CrappyMowersInc on the
other hand does not implement our Lawnmower interface, and therefore does not provide the
result we want.
Program To an Interface
We now come upon another idea relating to interfaces, and that is to program to an
interface, not an implementation. What it means is that if you have a class that will need to
have multiple different ways to do the same thing, you can create an interface. Let’s
imagine a landscaping company that is going to make use of our mowers. The company is
going to need to cut the lawns of its customers. It doesn’t matter if they do it with
a JohnDeere, a Kubota, a push mower, or a pair of scissors. As long as they get the job
done right, the customer will be happy. First off, let’s create a landscaper class that makes
use of a JohnDeere to cut lawns.
<?php
class Landscaper
{
protected $mower;
protected $customer;
Things are going great. We have already helped two customers today and they are thrilled.
Unfortunately, the blade on our JohnDeere hit a rock, and is now damaged. We don’t have
any spare parts, so it looks like we’ll need to use our backup Kubota to finish the last job of
the day. Let’s try that.
<?php
oh no! The Henrys are upset since we are unable to finish the job. The problem is, we
passed in a concretion, or implementation, into the constructor of the Landscapingclass.
Instead, we should have programmed to an interface. This way, we can swap out the John
Deere for a Kubota and it will work just fine. The reason it will work just fine is because
both the JohnDeere class and the Kubota class implement the same interface. This means,
they can complete the same exact behavior, which in this case is to cut_grass(). Let’s
update our code to be more flexible. Check out this one small change we make to our
Landscaper class.
<?php
interface Lawnmower {
public function cut_grass();
}
Notice that we now pass in an interface into the constructor of the Landscaper class. Now
when we new up that class later on in our client code, we can pass in a JohnDeere or
a Kubota, and nobody squaks! The class no longer cares what you give it, or how it
completes it’s job. As long as it can complete the job, which in this case is to cut grass,
everything works. Don’t believe me? Let’s make the Landscaping crew cut the grass with a
pair of scissors.
<?php
class Landscaper
{
protected $mower;
protected $customer;
It seems like there are a million ways to word this, so here is another one. A class should
have one, and only one reason to change. Say what? That doesn’t sound all that helpful,
what does it mean to have one reason to change. (Damn you nerdy programming geeks).
The way I understood this is to think of editing code. When you have a program, and you
want to change it’s behavior, what do you do? You scour through the source, find where
the behavior you want to change is, and hack away. In object oriented terms, that could
mean a situation like the following. Imagine you build custom cars and you deliver this
model to a customer.
<?php
class Car
{
public function speed()
{
return 'go fast';
}
$car->speed(); // go fast
$car->steer(); // turn left
This code breaks the Single Responsibility Principle. We know this because, what if your
customer says that he only wants his car to go slow and turn right. This is a problem since
you just delivered a car that can only go fast and turn left. So you have to go back to the
drawing board and edit your Car class in Two places. This is the breakage of the SRP, one
class with two reasons to change. Here is a different way to write the same code using
multiple classes. This way, we extract specific behavior into its own class. We’ll have
a Car class which of course is our car. We’ll also create an Accelerator class and
a Steering class. Even before we write any code, it is pretty clear what the responsibility of
each class is. This way, if the customer says that he wants to go slow instead of fast, we
only change one class. Let’s see.
<?php
class Car
{
protected $speed;
class Accelerator
{
public function go()
{
return 'going fast';
}
}
class Steering
{
public function turn()
{
return 'turn left';
}
}
So in this first iteration, we still have the same behavior. At this point however, each class
has only one reason to change. If we want to change the speed, we change
the Accelerator class only. If we want to change the steering, we change
the Steeringclass only. This way, we use a suite of classes to build up an object
(Hi Dependency Injection!). Anytime someone comes along after the fact and asks for a
change, we simply find the one class that has that one responsibility, and we change it.
Let’s change the Accelerator class.
<?php
class Accelerator
{
public function go()
{
return 'going slow';
}
}
This way, we made only one change in one class. We don’t even have to touch
the Carclass. It is oblivious to these things. All it knows is that it will be able to call
a speed()method, and it will do what it is supposed to. Running our client code, we find the
speed has in fact been changed.
<?php
class Steering
{
public function turn()
{
return 'turn right';
}
}
With this one change to the responsible class, we can again run our client code, and all is
fixed.
<?php
The Open Closed Principle is another concept in our study of the solid design
approaches in the object oriented style. You may have heard the idea that code
should be open for extension but closed for modification. Ok. Really what this
means is that when writing code, we should aim for the ability to change
behavior without having to actually change the code. Another way of saying this
is to program in a way so that the code does not need to be changed each time
the requirements of the project change. Like most things solid, it sounds great,
and is far easier said than done. It is a worthy principle to investigate however.
No Area Calculations
Pretty much every tutorial under the sun uses the example of calculating the area of
different shapes to illustrate the open closed principle. Let’s not do that. We need to create
something from our imagination if we really want the concept to stick. We will take the
concept of delivering Pizzas. Sounds much more fun than calculating the area of shapes.
Instead of dealing with how to calculate an area, we’ll work on how to deliver a Pizza. As
such, we need a PizzaDelivery class.
<?php
class PizzaDelivery
{
public function deliver()
{
$prepare = 'place pizza in car';
$travel = ' and drive down the road';
$customer = ' then give pizza to happy customer';
return $prepare.$travel.$customer;
}
}
$pizza = new PizzaDelivery;
echo $pizza->deliver();
// place pizza in car and drive down the road then give pizza to happy customer
Here we have a perfectly good class that is able to deliver Pizza in a fine manner. It turns
out however, that your Pizza Job is going above and beyond. Not only will they drive pizza
across town, if a customer lives on an island, this Pizza Restaurant will Bring it to them
right across the water. Now you are the Pizza delivery guy. Is your deliver method going to
work right when you need to travel by water? It might go something like this.
<?php
class Car {}
class Boat {}
class PizzaDelivery
{
public function deliver($transporter)
{
if(is_a($transporter, 'Car'))
{
$prepare = 'place pizza in car';
$travel = ' and drive down the road';
$customer = ' then give pizza to happy customer';
return $prepare.$travel.$customer;
}
if(is_a($transporter, 'Boat'))
{
$prepare = 'place pizza in Boat';
$travel = ' and sail across the bay';
$customer = ' then give pizza to happy customer on Nantucket';
return $prepare.$travel.$customer;
}
}
}
$pizza = new PizzaDelivery;
echo $pizza->deliver(new Boat);
// place pizza in Boat and sail across the bay then give pizza to happy customer on Nantucket
Just like that, you are now able to deliver Pizza by boat! You got the Pizza to the
Nice!
customer on time, she was so thrilled that she invited you in to watch Breaking Bad. Before
you go popping the champagne however, you need to know, you just broke the open
closed principle. How so? Well, when your Pizza shop decided to implement a new
behavior, you had to go back and change the original code to fit that need. In addition, the
dead ringer here is that you are doing type checking inside the class to decide which
behavior to take. Our PizzaDelivery class should be able to simply call a deliver method,
and get the job done, whether by Car, Boat, or Plane! Let’s clean things up (or dry up,
make solid, remove smell, whatever you want to call it). Our goal is to simply have a
method call something like this:
<?php
$pizza->deliver();
and our Pizza will be delivered, no matter how or where it gets delivered to. We can do
this!
<?php
interface Deliverable
{
public function deliver();
}
class PizzaDelivery
{
protected $transporter;
So what did we do here? We removed the need to do type checking inside our
PizzaDelivery class. By doing so, we can change behaviors in the application, without
touching the code. We are following the convention of closed for modification and open for
extension. Here is the process we followed to achieve this.
• Extract the behavior for the deliver() method out of the PizzaDelivery class
• Create an interface Deliverable which defines the contract for delivery
• Create new classes as needed that implement the interface to add behavior
With our interface in place, we were able to leave our PizzaDelivery class, as well as our
client code, untouched. All we had to do was add a new Spaceship class and have
it implement our Deliverable interface. Done.
We’re moving forward with our study of the SOLID design principles, and now
we have made it to the L. The L stands for Liskov Substitution Principle or
LSP and is named after the creator of the principle, Barbara Liskov. The formal
definition is very verbose, so in this tutorial, we will cover the topic as if we are
writing the first draft for the book, “The Liskov Substitution Principle For
Dummies.” Let’s learn a bit more about this principle now.
If it looks like a Duck, Quacks like a Duck, but needs batteries, – You probably have the Wrong
Abstraction.
-the internet
I believe the idea that this is getting to is that, once you start relying on abstractions in your
programs, it becomes important that those abstractions are able to be interchanged freely
without causing breakage to the program. Stack Overflow has this quote in the most
popular answer to the question.
Functions that use pointers or references to base classes must be able to use objects of derived
classes without knowing it.
-Robert Martin
It turns out this actually comes from Robert Martin, as a paraphrase for Barbara Liskov’s
own official definition here:
What is wanted here is something like the following substitution property: If for each object o1 of type
S there is an object o2 of type T such that for all programs P defined in terms of T, the behavior of P
is unchanged when o1 is substituted for o2 then S is a subtype of T.
-Barbara Liskov
In our little world of working with dependency injection and type hinting in PHP and
Laravel, this would mean something like this. Given a class A that depends on B, if we pass
in a C when we initialize A, everything should still work perfect. Let’s explain this in code.
We want to write a program, and the only goal is that it outputs a string that says, “doing
something”. Here is our client code, or our program.
<?php
// doing something
Perfect.We wrote a program that does what we want it to do. Now, the Liskov Substitution
Principle states that we should be able to create a new class that extends B, and when we
pass in that derived instance, instead of the original, everything will still work. Another way
to say this is that, derived classes must be substitutable for their base classes. With
that, lets create a new class C that extends B.
<?php
class C extends B {
public function dosomething()
{
return 'doing something';
}
}
Now, let us substitute the child class for the base class in our client code.
<?php
// doing something
Nice. Our program still works perfect, even though we pass in a C (derived) instead of
a B (base). Note that we did not even change anything in Class A, it still expects to receive
an instance of class B in its constructor. For all intents and purposes, the Aobject basically
still believes that it is calling a method on a B object when in reality it is calling a method on
a C object. This is the Liskov Substitution Principle in action. Let us now break the LSP
with a new class D that also extends B.
class D extends B {
public function dosomething()
{
return 'doing something ELSE';
}
}
Now we can call our client code again, and pass in a D instead of a B or C.
$a = new A(new D);
$a->amethod();
Technically, the program still runs, but we are not meeting the objectives of the
Fail.
program. It is not behaving as intended. Recall that our program is supposed to output
“doing something”. When we pass in the base class B, it correctly outputs “doing
something”. In fact when we substitute our base class of B for a derived class C, our
program still outputs “doing something” so it is working as designed and passes the LSP.
Finally, we pass in a D instance, and suddenly our program outputs “doing something
ELSE”. We swapped out our base class with a derived class, and the program broke. This
is the most basic example of the Liskov Substitution Principle I could think of.
Interface Design
At this point, we know how to use an interface in our programs. This is great, but we can
still run into problems with interfaces as well. Namely, with the Interface Segregation
Principle, we want to be sure that we don’t stuff our interfaces with the kitchen sink of
methods. If we add too many methods to our interfaces, they become too fat, and we start
to lose some of the benefits of solid that we are trying to achieve. Like always, lets take a
look at some code to see what we mean.
<?php
class Underling {
public function program()
{
return 'Program initech systems to deposit fractions of pennies to private account';
}
public function filetps()
{
return 'Place cover sheet on TPS report before going out';
}
public function collate()
{
return 'Collect and combine texts, information, and figures in proper order.';
}
}
class Lumbergh
{
public function harass(Underling $underling)
{
$underling->program();
$underling->filetps();
$underling->collate();
}
}
To begin, we have a Lumbergh class which has a harass method that depends on
an Underling to function. We can see that an Underling should be able
to program, filetps, and collate. So far so good we think. Lumbergh is able to
sufficiently harassany new underlings that come across his path. Now what happens when
Lumbergh needs to bring in some consultants to Initech. How will that play out? Lumbergh
should be able to harass Underlings as well as Consultants with equal impunity. Well,
maybe we can set up an interface and make Underlings and Consultants implement that
interface so that Lumbergh can harass them. Let’s try it out.
<?php
interface UnderlingInterface {
public function program();
public function filetps();
public function collate();
}
class Lumbergh
{
public function harass(Underling $underling)
{
$underling->program();
$underling->filetps();
$underling->collate();
}
}
interface UnderlingInterface {
public function program();
public function filetps();
public function collate();
}
class Lumbergh
{
protected $underling;
public function __construct(UnderlingInterface $underling)
{
$this->underling = $underling;
}
public function harass()
{
$this->underling->program();
$this->underling->filetps();
$this->underling->collate();
}
}
The solution to an ISP problem is to divide the interface into smaller pieces. It is ok in fact
to have an interface that has only one method. The problem comes in when you have an
interface that just has method after method after method after method that one must
implement. The more methods that need to be implemented, the greater the chance for
ripple effects in your program.
First off, we can break out our UnderlingInterface into
a ProgrammableInterface, FiletpsableInterface, and CollatableInterface.
Not Ideal
interface UnderlingInterface {
public function program();
public function filetps();
public function collate();
}
Better
interface ProgrammableInterface{
public function program();
}
interface FiletpsableInterface {
public function filetps();
}
interface CollatableInterface {
public function collate();
}
Now we can update our Underling and Consultant classes to implement only the
interfaces that they need to.
interface HarassableInterface {
public function answer_to_Lumbergh();
}
interface UnderlingInterface {
public function program();
public function filetps();
public function collate();
}
interface ProgrammableInterface {
public function program();
}
interface FiletpsableInterface {
public function filetps();
}
interface CollatableInterface {
public function collate();
}
class Lumbergh
{
protected $underling;
Right here we have an example of a high level module (The Handle) and a low level
module (The Tips) that depend on the same abstraction (The hexagonal shape). Not only
can you change out tips as you like (low level modules), you can also change out the
Handles (high level modules) as you like as well. This is true dependency inversion. Here
is my best stab at implementing this in code. If you have a better solution, please do let me
know so I can update it (contact @vegibit)
<?php
interface Hexagon {
public function shape();
}
abstract class Handle {};
abstract class Tip {};
class Tool {
protected $handle;
protected $tip;
No matter which handle or tip we choose, as long as they make use of the hexagon
Cool!
shape of our interface, we can interchange and plug and play at will.
Another example of the dependency inversion principle is that of the standard power plug.
A house has a means, or an interface to provide power, and that is by way of the standard
wall socket outlet. We have all kinds of electronic gadget makers that want to sell you their
wares, but they depend on electricity to work. The bright folks that build these boxes do not
leave it up to you to figure out how to get power into those devices. They are smart enough
to conform to the interface that they will need to use. The house says, I will provide power,
but I will only do it through this interface. The gadget makers gladly implement that
interface, and now you are free to plug in your Xbox, Playstation, Nintendo, iPhone
charger, refrigerator, Ultra HD Tv, and more into the given interface (the power outlet).
Chapter 8: Linux
How To Get Started With Linux
If you haven’t already, it’s time to Get Started With Linux. As web developers,
we work with Linux all the time, even if we don’t know it. Linux powers almost
all of the web servers out there on the internet. LAMP is the acronym that
stands for Linux Apache MySQL PHP. Microsoft also has the option to support
web developers and serve websites with its IIS Internet Information Server
technology, but Linux is far and away the more commonly used platform. Since
getting up and running with VirtualBox and Virtual Machines, Linux is now a
more interesting option to investigate further. Everyone has access to Linux in
one form or another whether through a VM on their machine, or by installing
something like Ubuntu as a dual boot or even full installation on a spare
machine. Let’s get started on a series of episodes featuring the awesome
Ubuntu Linux OS.
Linux Is Everywhere
Linux truly is everywhere, and it is so good at what it does, it is almost invisible. That is to
say that as technology gets better and more developed, it disappears into the background
and seamlessly does its job without the user even knowing about it. Again, for us, it’s use
is in serving websites using Apache or the even more incredible NGINX. Almost everyone
uses Linux however without even knowing it. Have you taken a flight lately? That traffic
control system is most likely powered by Linux. Bought or sold a stock in the financial
markets? Linux powered. Read about the Large Hadron Collider? Linux. International
Space Station? Linux. So as you can see, Linux is in places you may have never known.
And they said it was just for websites!
The Linux Filesystem Hierarchy is a key concept you will need to understand.
When working on the command line in Linux, you need to have a way to get
around so to speak. When all you have is a cursor just blinking at you, it can
give the feeling of “ok, what now”? Well, there are a handful of commands to let
you begin to navigate around the hierarchy of the Linux filesystem. In this
episode we’ll take a look at a few of them starting with pwd, which prints the
current working directory, cd, which allows us to change to another directory,
and ls, which provides the ability to quickly list the files and folders contained
within a directory.
cd ~user Goes from te current working directory to the home directory of the user. For example cd ~vagrant goes
to the home directory of user vagrant.
Let’s take a closer look at Linux Files and Directories. Our Linux system has a
whole boatload of files. In our case we’re working with homestead which is a
custom built Ubuntu Linux server running as a Virtual Machine on VirtualBox.
To check how many files and directories a particular directory is comprised of,
we can use the tree command with the –a switch to include all files and
directories. When we run this command on our home directory, we get 2,132
directories and 11590 files. That is a lot of directories and files! Let’s learn a bit
more about those Linux Files and Directories now.
Linux Files and Directories
/boot/grub/grub.conf This file is used to configure the boot loader, or what you see when the system first powers on
/boot/vmlinz The Linux kernel itself. Steer clear of this or Linus Torvalds will drop a Watermelon on your head.
/dev This directory holds what are called device nodes. It is in /dev that the kernel keeps a list of devices
the system makes use of.
/etc This directory holds configuration files that apply globally across the system. There are also a few
shell scripts that launch at boot time. Files in /etc are normally readable text which makes sense as
config files and simple scripts should be human readable. This is a good directory to become familiar
with.
/etc/crontab This is a file that handles when to run cron jobs. These are automated tasks, and can be extremely
useful.
/etc/fstab This is a text file that has information about storage devices such as hard drives and their mount
points within the file system.
/etc/passwd This is a text file that contains all of the user accounts for the system. If we use the less command on
our system, it looks like this:
/home This directory is the home for all users on the system. So if you had a user Bob, he might have a
directory located at /home/bob. Standard users can only write files in their directory. This prevents
them from turning you Linux machine into a brick.
/lib This directory has shared files with get used by many core processes in the Linux system.
/lost+found Yes, even in operating systems there is a lost and found. The purpose of this directory is to attempt
system recovery in the case of a crash. Normally, this directory is empty.
/media This directory handles mount points for things like USB drives or other types of removable media
which mount / unmount automatically on insertion.
/mnt This is more of a generic mount point and may contain information about the hard disk in use on a
dual boot machine.
/opt This directory holds software that as its name implies, is optional. For example, the software
contained here is not core level, it is an add on, much like Google Chrome.
/proc The proc directory has all kinds of magical voodoo happening within it. Think of it as a virtual
filesystem of the Linux Kernel. It’s best not to mess around in this directory unless you have a very
specific reason to.
/sbin This directory holds system programs, or binaries as they are called in the Linux world. These are
programs that are typically run by the superuser, as they carry out vital system tasks.
/tmp Just like in Windows, you will have the need for temporary files during normal operation of the
system. In Linux, those files get written to and deleted from this directory all the time.
/usr This directory is HUGE. It contains all programs and files used by users of the system. By running a
tree command on our Linux homestead system, we returned a result of 10,522 directories and
71,046 files.
/var This directory contains files and directories that may be dynamic. Data that gets updated frequently
like databases, mail, and others are held here .
/var/log This directory has all kinds of log files that are useful for debugging various system issues.
Conclusion
We’re making good progress getting up to speed with all of the basics of Linux Files and
Directories. In this episode, we created a nice table to remind ourselves what some of the
more commonly used directories and files are used for. One last helpful trick, when you
are practicing all of this navigation at the command line, you may occasionally want a
“fresh start” so to speak. Simply type the command clear at the terminal and you will once
again have a nice blank slate to work with.
The Linux files introduction episodes so far have been excellent for a gentle
primer on how to get up and running with Linux using Ubuntu. Now we can get
to some even more interesting challenges. In fact, that is how this Linux Series
is designed to work. We start with the absolute basics, and move on to more
challenging tasks. In this episode, we’ll be looking at copying, moving, creating,
deleting, and overall just fully manipulating the files and directories on our Linux
system. To do this we will make use of the four most commonly used
commands in the Linux operating system. Those commands are cp to copy files
and directories, mv to move and rename files and directories, mkdir to make
new directories, and rm to delete files and directories. Let’s get to it.
Build A Linux File Sandbox
The best way to get used to these commands is to simply put them to use. Just like we do
with our PHP, HTML, and JavaScript tutorials, we’ll create a sandbox which we can test
out the things we learn. Let’s do that now.
mv Command Reference
Since there are a few ways to the mv command to use, it may be helpful to have a
reference to document how the command works in different situations. Note the table here.
mv fileone filetwo Moves fileone to filetwo. In the case that filetwo exists, it will be
overwritten with the contents of fileone. If filetwo does not exist, it will
be created. Either way, fileone ceases to exist.
mv -i fileone filetwo By adding the -i switch to this command, the user will get a warning or
prompt before anything gets overwritten. If you’re unsure, this is a good
thing to do.
mv fileone filetwo directory1 This moves fileone and file two into the directory directory1. directory1
must already exist for this to work.
mv directory1 directory2 The result of this command will change depending on if directory2 exists
already or not. If it does exist, the entirety of directory1 will be moved
into directory2. If however directory2 does not yet exist, it will be
created, then directory1 will be moved into it.
cp Command Reference
Likewise with cp, you’ll want to know what the expected result is of the commands you run.
cp fileone filetwo This would copy fileone to filetwo. If filetwo does not exist, it is created. If
filetwo exists, it is overwritten with the contents of fileone.
cp -i Adding the -i switch will give you a prompt before overwriting any existing
file.
cp fileone filetwo directory1 This will copy both fileone and filetwo into the directory directory1.
cp directory1/* directory2 By including a wildcard, all the files in directory1 are copied into
directory2. You can also get granular, for example if you wanted only html
files you would use *.html
cp -r directory1 directory2 By adding the -r switch this will copy the directory directory and
everything in it, to the directory directory2. If the directory directory2
does not exist, it is created and will contain the same contents as the
directory directory1.
yo*.html matches any file that starts with yo followed by any characters and
ending with .html
TONES.[0-9][0-9][0-9] matches any file that starts with TONES. followed by exactly four
digits
awesome?? Matches any file that starts with awesome followed by exactly two
characters
*[[:lower:]712] matches any file that ends with a lowercase letter or the digits 7, 1,
or 2
[![:digit:]]* matches any file that does not start with a digit
These patterns share similarities to regular expressions. To learn more about how Regular
Expressions work, check out our post that outlines learning about regular expressions.
Linux Redirection
stdin
The first thing to know is that standard input is identified by the less than < character. The
syntax is typically program < input. The easiest way to see how this works is to simply
complete an example.
vagrant@homestead:~/Code/Laravel$ ls
app bootstrap composer.lock phpunit.xml readme.md vendor
artisan composer.json CONTRIBUTING.md public server.php
vagrant@homestead:~/Code/Laravel$ wc < phpunit.xml
18 24 567
vagrant@homestead:~/Code/Laravel$
In this snippet we simply list the files in our Laravel directory and then use the word count
program and feed it information using standard input. The result is output to the terminal
and what those numbers mean is 18 words, 24 lines, and 567 characters. Now, notice that
the name of the file is not present in that output. That is because wcis not aware of the file
it was provided. In fact what happened is the contents of that file where read in through
standard input to wc, and wc simply outputs information about that stream so to speak to
the terminal.
xargs
Not all commands accept information on standard input. For example the echocommand is
one such example. There is a work around however. Linux has a handy little command
called xargs, and what it does is to act as a transcoder of sorts that accepts standard input
and then formats that data as arguments so to speak for the next command in the chain.
Let's demonstrate this whole concept now.
vagrant@homestead:~/Code/Laravel$ ls | echo
vagrant@homestead:~/Code/Laravel$ ls | xargs echo
app artisan bootstrap composer.json composer.lock CONTRIBUTING.md
error.txt files.txt phpunit.xml public readme.md server.php vendor
vagrant@homestead:~/Code/Laravel$
What we see here is that the first instance of using ls and echo together via the pipe is that
we get a blank line. This is because the echo command expects some data to actually
echo out to the terminal. By including xargs after the pipe however, we can see
that echo now successfully outputs the data it received via the output of ls by way
of xargs. Hopefully that makes sense. When in doubt, just fire up your terminal and
practice these techniques a few times.
tee
The tee command is pretty slick because it acts like a T. Meaning, picture feeding data into
the bottom of a capital letter T, and then having that data get blasted out of both the left
and right spigots of the T. That is sort of what tee does for us. Let's see an example.
vagrant@homestead:~/Code/Laravel$ ls | tee teeout.txt
app
artisan
bootstrap
composer.json
composer.lock
CONTRIBUTING.md
error.txt
phpunit.xml
public
readme.md
server.php
teeout.txt
vendor
vagrant@homestead:~/Code/Laravel$ cat teeout.txt
app
artisan
bootstrap
composer.json
composer.lock
CONTRIBUTING.md
error.txt
phpunit.xml
public
readme.md
server.php
teeout.txt
vendor
vagrant@homestead:~/Code/Laravel$
We can see in this example that the command ls | tee teeout.txt did two things. It sent
the output to the terminal, as we can see by the file names listed, and it also sent that
output to a file named teeout.txt. To confirm this, we run cat teeout.txt and voila, we
can see the contents of that file containing the same output that was sent to the terminal.
Pretty slick!
Background Process
To place a process in the background, it is very easy. All you need to do is add the
ampersand & character at the end of the command to put the job in the background. Let’s
see how.
vagrant@homestead:~$ sleep 500 &
[1] 4994
vagrant@homestead:~$
Now here we can see that the process was started, but we get the terminal back to
continue doing our work without issue. The feedback we are given is helpful information. It
states that this is Job number 1 with a process ID of 4994. To confirm this, we can simply
run the jobs command like so.
vagrant@homestead:~$ jobs
[1]+ Running sleep 500 &
vagrant@homestead:~$
Welcome to this Vi Editor Tutorial for beginners. Vi is a robust and powerful way
to work with files on Linux. Now, we say wonderful with a hint of sarcasm as
some people do in fact love vi, while others despise it. It might be due to the
nature of vi in that it is entirely keyboard based, meaning you must learn
specific key combinations and sequence of key presses to get anything done.
You won’t be moving the cursor around a file with the mouse like you might be
used to. Fear not however, since once you start getting good with vi, your geek
status will elevate to the next level, and you just might like working with vi on a
daily basis. Let’s check it out in this vi editor tutorial for beginners.
Command Mode
One thing to be aware of, is that vi starts in command mode. If you’ve ever opened vi
before and found that nothing works, or that you couldn’t even type any text, you were
likely stuck in command mode without realizing it. It is things like this that push newcomers
to vi away, it seems like the thing doesn’t even work! Command mode however is a way to
allow quick access to all the important commands you can apply to files such as write, quit,
and so on.
Insert Mode
Insert mode on the other hand is needed so that you can begin to actually type some text
into the file. We can enter into insert mode easily by hitting the i key. This is what we did in
the example above in order to type out the simple example text. To leave insert mode, you
simply hit the esc key which brings you back to command mode. This is a unique aspect of
vi and as you use the software more, switching between insert and command mode will be
second nature.
register
In Linux and vi, the idea of a clipboard is called the register. There really isn’t much more
to know beyond that. Just understand that if you copy or cut information, it goes to the
register in vi.
yank
The yank concept is the equivalent of the copy command in the windows world. You can
yank in several ways such as to yank the current line with yy, yank a word with yw, yank a
single character with yl, or yank multiple lines with something like 4yy. This would yank 4
lines. So let’s test a few of these out.
vagrant@homestead:~$ cat file.txt
This is a new text file created with the vi text editor.
This is a new text file created with the vi text editor.
Above this line, is a blank line.
Above
Lets check out some of the other things we can do with the vi editor.
This is some text
which is broken across
multiple lines so
we can test the multi
line yank with something
like 6yy
This is some text
which is broken across
multiple lines so
we can test the multi
line yank with something
like 6yy
vagrant@homestead:~$
This is a simple example of using yy, yw, 6yy, and p to yank various amounts of text to
the register, and then put the resulting characters back into the file. We did not
mention p yet, but what it does is to put any contents in the register into the file.
delete with vi
You’re in luck my friend. If you’ve become familiar with the y command and the various
combinations of how to use it, you already know how to use the d command for delete. In
other words, all of the combinations that we used for y such as yanking a whole line
with yy, or yanking a single character with yl, yanking a word with yw, or yanking multiple
lines with nyy, can be directly applied to d delete. All you do is swap out any instance
of y for d and now you are not simply yanking, but deleting the text being worked on. You
can use this in two ways. First, you can use it to simply eliminate any characters you would
like to from the file, or second, you can use this to move letters, words, or lines, to different
areas in the file. This is because when you use d, it places the deleted contents in
the register, so you can easily use the pcommand to put those contents where ever you’d
like.
Searching With vi
Let’s say you’re examining a large configuration file, and not just some basic text like you
have here. Well in a case like this, it is going to be helpful to be able to quickly search
within the file. We can do this with vi by using special characters in command mode. The
forward slash / allows you to search forward. So just as a really basic example, let’s say
you need to search for the letter a. You would type /a in command mode and hit enter. It
stands to reason that the letter a may occur many times in a text file. If you would like to
find the next occurrence of the search just hit the n key. If you’d like to find the previous
occurrence simply type capital N. It’s a really quick way to move through the file. To begin
with searching backwards you would use ? instead of / as in ?a for this example.
Execute Mode
Some would refer to this as a whole separate mode, but really it’s just a subsection of the
command mode. You can enter this state by typing the colon : while in command mode.
This will create a prompt at the bottom of the editor beginning with :. It is from this mode
where you can save or write changes to a file. You can also quit without saving and so on.
Once you’re at the : prompt, you’ll be typing things like w, wq, q! and so on.
vi Summary
Now that we have run through the very basics of using vi with Linux, let’s assemble our
own summary of commonly used commands. It helps to write these out as they’ll stick in
your memory easier.
/ while in command mode, entering / will start a forward search
n once you are searching, n will take you to the very next occurrence
h, j, k, l, h takes you left, j moves down, k goes up, and l is for moving right
There are a few different Command Types In Linux. In fact, there are four
command types in Linux. So just what are these commands? First up, there are
executable programs or compiled binaries. For example if you run ls /usr/bin,
you will be greeted with a large collection of programs. These are most often C
or C++ programs which have been compiled, or small scripts written in bash,
Ruby, Python, or Perl. A second type of command is that which is a built in.
Built in commands are part of the shell itself. For example, the
convenient pwd command is actually a shell builtin. Some other built ins
are break, cd, continue, eval, exec, exit, export, getopts, and more. The third
type is that of a shell function. These are small scripts that are integrated into
the environment and are useful for scripting repetitive administration tasks. Last
up we have the alias, which is a super way to define macros or shortcuts so to
speak of existing commands to reach a desired result. Let’s take a closer look
at command types in linux now.
5 file formats
If you want to search a specific section, you can do so in the format of man number
command, however most times leaving off the section number is quickest and easiest.
It’s helpful to learn a few Linux Keyboard Tricks. You may have noticed that
when working with Linux at the command line, everything seems like a shortcut.
In other words, instead of having descriptive commands such as list files, or
change directory, we have things like ls and cd. What’s up with that? You might
call it laziness, but really, its more of trying to get the most amount of work done
with the fewest keystrokes. In this vein, there are a bunch of Linux keyboard
tricks that we should know to help us along when making use of the command
line. Let’s investigate this topic now.
• CTRL-U Cuts the text from where the cursor is located to the beginning of the line.
• CTRL-K Cuts the text from where the cursor is located to the end of the line.
• ALT-D Cuts the text from where the cursor is located to the end of the current word.
• ALT-backspace Cuts the text from the cursor location to the beginning of the word.
• CTRL-Y yanks the text from the register and inserts it at the location of the cursor.
aa-exec apport-bug ar
aclocal-1.14 apropos as
acpi_available apt at
vagrant@homestead:/$ b
badblocks bsd-write byobu-screen
bc byobu-ctrl-a byobu-status
1 bg byobu-enable-prompt byobu-ulevel
vagrant@homestead:/$ c
1 Display all 100 possibilities? (y or n)
vagrant@homestead:/$
In this example we simply type the letter a and then the tab key twice and it lists all of the
possible commands that begin with a. We do this again for the letter b, and then c,
however since the letter c would return 100 results, we chose not to list them. Try it out for
yourself in your terminal.
2 ls
3 php --version
4 clear
5 composer --version
6 clear
7 exit
8 cd /
9 l
0 10 c
1 11 a
2 12 c
3 13 history
4 14 php --version
5 15 composer --version
6 16 c
7 17 history
8 18 ls
9 19 cd
0 20 top
1 21 pstree
2 22 c
3 23 history
4 24 ls -a .ba
5 25 ls -a
6 26 c
7 27 history
vagrant@homestead:~$ clear
Linux Permissions
Ubuntu has a nice overview of file permissions. This is a good resource to have.
total 8
Say What?When we look at the output, at first it seems like just a random collection of
characters with no meaning. Each character has meaning however, and each column has
meaning. We placed this output into a table to drive home the idea of the seven different
columns on output. Let’s take a look at column three and column four, and notice that they
have names. These names are the owners of that particular entry. Column three is
for User and column four is for Group.
total 8
We can see that the ubuntu.txt file now has an owner of root and a group
Excellent.
membership of admin. Great work.
total 0
Ok we can see our files as well as the associated user and group. Lets test out the -Rflag
with the chown command to change both the user and the group recursively.
vagrant@homestead:~$ sudo chown -R root:admin directory
vagrant@homestead:~$ ls -l directory
total 0
Just like we expected, both the user and the group have now been updated for the
directory and all of it’s contents in one swoop. Of course this is a bit of a nonsensical
example, but if you need to change a user or group on hundreds of files in a directory, you
will come to love the recursive ability of the command line. Another thing you’ll notice is
that its easy to use chown to not only change users, but groups. It does seem to
make chgrp a bit redudant, but both exist, so feel free to use what you like. Let’s
use chown to modify only the group membership, but not ownership.
vagrant@homestead:~$ sudo chown :vagrant ubuntu.txt
drwxr-xr-x
Representing Permissions As Octal Numbers
The string of 9 characters used to show permissions on a resource can also be
represented as an octal number. This means instead of something like rwxrwxrwx, you
could simply refer to this as 777. How does this work? Lets see.
Octal Assignment
• r=4
• w=2
• x=1
d 7 5 5
– rw- rw- r- –
– 6 6 4
The table above is easy to figure out, and this is how you can figure out exactly what
permissions a resource has by simply looking at the three digit octal value. We know
that read has a value of 4, write has a value of 2, and execute has a value of 1. This
ingenious method allows the full range of permissions to be assigned using only 3 digit
spaces. Here is the full chart of octal to permission representation.
octal permission
0 - - -
1 - - x
2 - w -
3 - w x
4 r - -
5 r - x
6 r w -
7 r w x
uo-rwx remove read, write, and execute, from both user and other
ugo+rwx allow full access equivilent to 777 for user group and other
SUID
The setuid bit is used on executable files. It is also sometimes known as set user id. If this
bit is set, the file will run as the owner of the file. What does this mean? Well, suppose
there is a file on the system that is owned by root. Along you come as a user account, and
you run that executable file. If the SUID is set, that file will run as root, even though you
might be logged in as Emmet. You typically don’t mess with the SUID, and it is dangerous
if configured improperly, but we include it for completeness.
GUID
GUID is used on both executables and folders. Group user id works similar to suid in that it
alters permissions whether it is set or not. If it is set on an executable file, then the file runs
with the permissions of whatever group owns the file. When applied to folders, the result is
that any files or folders created within the parent folder will be owned by the group. In other
words, all new files or folders will inherit group ownership from whatever group ownership
the parent folder has.
Sticky Bit
Finally, we have the sticky bit. It’s not actually used all that much these days on files, but
there are some use cases for it on folders. The most common place we see it in use is on
the /tmp directory. What it does is to say that only the owner of a file or folder, can delete
that file or folder. This makes perfect sense for the /tmp directory because there will be
multiple users and groups writing to and reading from the /tmpdirectory. Well guess what.
You don’t want other users to come along and delete anything that you need access to.
Now when we say users, these often refer to the user processes used by applications, not
actual human users.
Representing SUID GUID and Sticky Bit
You are surely familiar with the format of 777, or 664, to represent permissions in Linux.
Well what about the times you see 4 digits like 4755, or 2775? The answer is that the first
digit is an octal representation of the SUID, GUID, and Sticky Bit. We already had a look at
how to calculate permissions using octal for the User, Group, and Other. Well, it works the
same way for SUID, GUID, and Sticky Bit. Let’s see how. Recall our list:
• r=4
• w=2
• x=1
Now simply update it to see how these values are set with regard to SUID, GUID, and
Sticky Bit.
• SUID = 4
• GUID = 2
• Sticky Bit = 1
Now you can simply add the numbers up to understand what is set. For example 1777 has
the sticky bit set, 2777 has the guid set, 4777 has the suid set, and 5777 has both the suid
and sticky bit set.
An Example SUID Use Case
The built in ping program is a good example of the SUID bit being set. Let’s see it in action.
vagrant@homestead:~/directory$ ll /bin/ping
-rwsr-xr-x 1 root root 44168 May 7 2014 /bin/ping*
vagrant@homestead:~/directory$
Do you notice anything funky there? That’s right, have a look at -rwsr-xr-x and notice the
letter s in there. What that means is, when I run the ping program from the vagrant
account, ping is going to run as root. See how that works?
An Example GUID Use Case
Suppose we have a script on the machine, and we want that script to run with group
permissions no matter who triggers it. Let’s see how to do that.
vagrant@homestead:~/directory$ sudo chmod g+s pretendscript
vagrant@homestead:~/directory$ ll
-rwxrwsr-x 1 vagrant admin 30 Feb 20 18:35 pretendscript*
vagrant@homestead:~/directory$
In this example we can see that the GUID is set by the s in the permissions -rwxrwsr-x.
The letter s is still used, however it is placed in the location of the executable bit for the
group permissions like you see here. In this case, this file will always run with the
permissions of the admin group.
Chapter 9: Virtualization
Introduction to Cloud Computing
Maybe you also need to consider disaster recovery and backup. Guess what, yep –
another server! This leads to a bit of a sprawling expanse of servers which become difficult
to maintain. Unsightly tower computers would be cluttering up the data center as this
process moved on. This was inefficient, but it is how things used to be done as we had no
other choice.
As this process continued, we eventually made a move to what people refer to as a blade
environment. So what is a blade? Well, if you are familiar with live music or you are a
musician, you might be familiar with the idea of putting your processing equipment in a
rack. The same exact idea applies here in data center computing. What we did was to take
traditional tower computers and stick them into a rectangular shape that could be rack
mounted. Each blade would typically take up one or two rack spaces, and would offer a
more converged solution in offering computing power to end users.
At this point, when a developer needed a new playground to play in, we would deploy a
build environment on one of our collection of rack servers to meet this need. We could also
create a disaster recovery scenario on the next available blade server. This provided for a
much greater density and availability or servers. At this point, we could fit maybe 20
servers in a rack mounted unit. This was good, but we still hadn’t begun to virtualize things
yet.
Enter Virtualization
Moving further along, we needed to make better use of the blade based computing rack.
Whereas before, one operating system was installed per available server and we would
run whatever applications we needed. It was the introduction of the Hypervisor which
changed all of this. Ince the Hypervisor came into play, it would be the software that ran
just above the bare metal. On top of the Hypervisor, one could run an almost limitless
amount of virtual servers or virtual machines to support whatever our imagination could
come up with. Of course the Hypervisor would be something like VMWare, Xen, KVM, or
Hyper-V.
The Hypervisor layer made it possible to virtualize entire machines and provide a pool of
computing resources to an end user. From there, a user would make a request of devops
or IT for a particular resource. In the old days, a physical server would need to be
deployed to support this request. Maybe the IT technician didn’t even have one available
right away, so the user would have to wait. This was not ideal. With the Hypervisor in
place, our devops person could now log into the virtualization platform and “spin up” an
instance of a new server. As if by magic, “Poof!”, here you go – a brand new Ubuntu server
machine. Want another instance for testing or disaster recovery? No problem, spin up
more servers in seconds. Maybe you need a Windows Server for testing. Check. Want to
test the ability to scale? Sure thing, spin up another instance and configure load balancing.
At this point, we can see the basic Hypervisor reduced time to market for users, decreased
dependency on physical hardware, and generally made things much easier. This is
Virtualization. Virtualization has progressed even further than this however.
Welcome To The Cloud
The cloud means many different things to many different people. At the end of the day
however, a cloud can be distilled down to three properties. A cloud should be…
• On Demand
• Elastic
• Self Servicing
Let’s examine some of these properties as they relate to the cloud.
On Demand: The on demand characteristic of a cloud means it can provide a service
almost immediately at the request of a user or endpoint. You don’t put in a ticket with the
help desk and hope for feedback within two business days. On demand means now, and
this is exactly what most all good cloud providers offer.
Elastic: When we say elastic, what this means is that the resources required to support
your service must be able to grow and shrink with ease. Of course we know Amazon Web
Services uses the term Elastic to describe this very feature of their cloud offerings.
Self Service: A cloud service is typically self service. This means anyone with a network
connection can log into a dashboard or admin panel, and deploy resources at will with no
need of a third party intervening. There should be no need for any physical deployment,
and no need to painstakingly build out an infrastructure. You just select your service from a
catalog of offerings and hit “go”.
Platform as a Service
Moving further along in this introduction to cloud computing, we will talk about PaaS or
Platform as a service offerings. PaaS is similar to IaaS but it offers an even higher level of
abstraction than does the IaaS paradigm. Let’s consider an end user that is a PHP
developer and wants to build an application for the cloud. In the IaaS paradigm, you would
need to provision your own virtual machine and operating system. Perhaps you would
deploy an Ubuntu Linux machine with an Nginx web server, a MySQL Database, and
some other data store technologies. You are just the developer however, you want to write
your code and forget about all of those steps. Configuring a full LEMP or LAMP stack by
hand is a lot of work with a lot of dials to turn and configure. If the end user is not up to this
task, one may consider to go the route of Platform as a Service. In this scenario, the
Service Provider moves further up the stack and handles even more lower layer resources
for you. With the operating system, middleware, and runtime all configured for you, all you
have to do is write and publish your application at this point. It is an even easier method of
launching your own service or application but do expect to pay a slight premium over
traditional IaaS offerings since more of the work is done for you. Examples of this type of
offering include Pagoda Box, Engine Yard, Fortrabbit, Heroku, Deis, Cloud Foundry,
Cloudbees, Appharbor, and many more.
Public Cloud
These are the types of clouds that we are all the most familiar with, since this is the most
common type of offering. Typically what this means is as an end user, we simply make
requests into the service provider cloud via the public internet and we get access to the
resources rendered as a public cloud.
Private Cloud
A private cloud works much the same way as a public cloud, but the difference is that the
hardware that makes all of this possible is OnPrem or on premises. This is what you will
commonly find today in large corporations which had networks and applications long
before IaaS and the public cloud even existed. A private cloud might work much the same
way as an Amazon Web Services would, albeit it is built and managed by a private
company for a specific set of users.
Hybid Cloud
Finally we come to the private cloud which is rapidly gaining in popularity. The hybrid cloud
makes use of the characteristics of both Public and Private Cloud paradigms in order to
best meet the needs of an organization. There are of course pros and cons to IaaS public
cloud services and Private OnPrem cloud services. Demanding clients in the technology
industry are now making use of the best of both worlds by using aspects of the public
cloud where appropriate and aspects of the private cloud for other use cases. One use
case for a hybrid cloud is the ability to move resources between the pubic and private
clouds as needed. In developing an application during the test phase, one might make use
of a public cloud. When the application is ready for production and security and safety are
of utmost concern, that resource can be migrated from the public cloud to the private
domain with relative ease in a hybrid environment.
• DAS makes use of SCSI which stands for Small Computer System Interface.
• NAS might make use of CIFS or Common Internet File System / SMB Server
Message Block.
• SAN makes use of iSCSI or FC, those being Internet Small Computer System
Interface and Fibre Channel.
Consider a scenario where there are some workstations that need a large amount of
storage. So much so, that a directly attached storage configuration would not be feasible. If
you don’t have the resources to build out a powerful, complex, and expensive SAN, then a
Network Attached Storage might be the way to go. In the diagram above, the application
servers on the right hand side are going to want to access the storage available on the
NAS appliances. NAS makes use of CIFS and NFS which do have a bit of latency and
chatter associated with them. Current iterations of NAS however have minimized these
caveats, and in a scenario where you need things like Microsoft Office, Sharepoint, and
generalized file and print services – a NAS makes perfect sense. One more quick tip for
NAS is to be careful making use of no_root_squash option. This allows an NFS share to
be mounted and written to as the root user by the hypervisor which could be a security
risk.
Thick vs Thin Storage Provisioning
One thing to keep in mind when provisioning storage on a NAS, is using thick vs thin
provisioning. They differ in the way resources are allocated. If you set aside one terabyte
of storage for a particular purpose as a thick provision, this is a hard set value. If the
consumer of that resource is only making use of 20% of that terabyte, this is wasteful. That
remaining 80% is sitting around as a wasted resource that others can not access. A better
use of resources would be to thin provision the storage. When you thin provision, the
storage acts in an elastic type manner. When you thin provision that same one terabyte,
the consumer still has access to the full terabyte but only on an as needed basis. If only
10% is being used, the other 90% will be available for use by the rest of the data center.
SAN Storage Fundamentals
Storage Area Networks sit at the pinnacle of data access. DAS and NAS work well in a
large percentage of installs. A SAN is implemented as a Fabric Topology via 10 Gigabit
per second Fibre Channel over ethernet technology. This is also referred to as FCoE. It is
faster, more scalable, less latent, more robust, more complex, and also generally more
expensive than DAS or NAS technologies. This Fabric Interconnect switching shares some
analogies to the LAN world if you are familiar. In a LAN, devices make use of MAC
addresses to uniquely identify themselves on a network. In a SAN, it is the WWPN or
World Wide Port Name which gets assigned to a port in the fibre channel fabric. Just as
with a LAN we can use Virtual LANS or VLANs to partition resources in the network, in a
SAN we can also make use of a VSAN. A VSAN is a virtual storage area network which
also provides a type of partitioning of resources within the SAN. In addition to using
VSANs, you can be more granular with Zoning within the VSAN. By making use of Zoning,
you can set up single initiator to single target, single initiator to multiple targets, or multiple
initiators to multiple targets. Within the fibre channel network, frames are routed by a 24 bit
field called the FCID. Also of note is that FCoE has a specific initialization protocol to
adhere to which includes VLAN Discovery, FCF Discovery, and FLOG I/F Discovery.
Another method of partitioning a storage resource would be via LUN masking. LUN or
logical unit number, identifies the logical piece of storage an initiator can reach. A LUN
may span multiple physical disks. Note that a SCSI LUN and Cinder Volume require that
their block device are attached to an instance before any file system commands can be
administered. In addition to file based storage, we have object based storage such as
OpenStack Swift, offering similar functionality to what you might find with Amazon S3.
The InterCloud
In cloud computing, we are now faced with many different flavors of the cloud. Of course
we have the Public Cloud, the Private Cloud, the Community Cloud, as well as the Hybrid
Cloud. The community cloud may be new to you. This particular flavor of cloud refers to a
specific use case cloud which is shared by many companies. Of all of these, the Hybrid
cloud is really winning mind share with information technology departments of the biggest
companies in the world. Businesses want the benefits of the cloud, but also need to be
aware of security and intellectual property considerations. In a hybrid environment, a
company may choose to make use of a private cloud for some aspects of the business, a
public cloud for others, and a community cloud for yet other business objectives. This can
be a slow, complex process, with challenges of administration. Cisco offers a solution
called the InterCloud to tackle these challenges head on to offer self service for hybrid
resources and secure connectivity between public and private Clouds.
There are three different components of the InterCloud. These are the Fabric Director,
the Fabric Provider Platform, and the Fabric Secure Cloud Extension. These
components work together to allow a cloud deployment model which makes use of
interoperability features of various different cloud providers. Instead of having disparate
pieces of software and platforms to administer, one can make use of this solution from
Cisco to act as the single point of management for a hybrid cloud deployment model. It is
an effor to provide consistency, compliance, control, and choice for the customer. The
InterCloud acts as a middleware to make seamless communication between private,
public, and community deployments.
Server Virtualization
In the past, the only way we could scale servers was to pack in more RAM and CPUs into
the existing hardware available to us. This is known as scaling up. When you ran out of the
ability to maximize any one machine any further, you started adding more physical
machines. This is known as scaling out. Over time, this process would repeat itself leading
to server sprawl, in efficient use of physical space, large cooling bills, and large electricity
bills. All of this changed with the miracle of the Hypervisor. The Hypervisor is a piece of
software typically installed on top of a computer node. The hypervisor does some really
cool things like masking server resources, or abstracting away the number and types of
physical servers from the end users. Surely you must be familiar with VMWare’s ESXi
platform, or the Linux KVM, and the Microsoft Hyper-V. These are all popular hypervisors
that you would likely find in any data center today.
Type-1 Hypervisor
Type-1 is the preferred method for server virtualization. Think of a Type-1 Hypervisor as a
bare metal approach, meaning the software sits directly on top of the hardware. There is
no intermediate operating system in place. VMWare’s ESXi platform runs directly on the
host hardware to control and manage the guest operating systems as a Type-1 hypervisor.
Type-2 Hypervisor
A Type-2 hypervisor sits on top of an operating system rather than the bare metal. This is
a popular approach to use on a Workstation where you would like to have access to
another type of operating system of application for various reasons. Think Oracle
VirtualBox, VMWare Fusion, and VMWare Workstation.
Server Virtualization Benefits
• Hardware Consolidation
• Uniform Resource Pools
• Simplified Resource Sharing
• Utilization Optimization
• Best use of physical hardware
• Less Expensive
Live Miration: Another amazing feature of server virtualization is the ability to transfer a
running virtual machine between hosts. When this happens, the I/O and CPU calls are
queued to ensure that during the transfer CPU and Memory state are moved, no
interruption to the clients can occur. In addition to this, when you have multiple virtual
machines on the same physical hardware, they can make use of an SR-IOV which
virtualizes the PCI host bus so it can be allocated to each guest machine.
Network Virtualization
Not only has server virtualization really exploded in popularity, but entire networks are also
now getting virtualized. SDN or software defined networking is taking over the data center.
If you think about it, we really need virtual networking in order to make server virtualization
possible. On virtual machines is the concept of a virtual NIC, vNIC, or Virtual Network
Interface Card. With the physical servers, we needed to of course plug them into a
physical switch to get network connectivity. In the virtual world, on our virtual machines, we
also need to “virtually” plug their virtual nic into a virtual switch. I know, it is a bit confusing!
With multiple virtual machines scattered across many different physical servers, how can
they communicate to one another. They do so by way of a DVS or Distributed Virtual
Switch. An example of this type of switch is the Cisco and VMware created Nexus 1000v.
The goal of the 1000v is to provide a consistent interface you will be familiar with as it
shares a similar feel to any other NX OS based switches. The 1000v makes use of ARP
Address Resolution Protocol, CDP, vPath for flow redirection in vService interaction, and
high speed VPC Virtual Port Channeling. You can even talk to remote data centers over
Layer 2 with OTV or Overly Transport Virtualization. An advantage that DVS has over
vSwitch is that it supports private VLANs. Port configurations make use of Atomic
Inheritance to provide a consistent configuration among all ports in a profile.
VXLAN
You may be familiar with a VLAN in the Layer 2 world. In the virtualized switching world,
we have VXLAN, and it’s like a VLAN on Steroids. With standard VLANS, you have the
ability to make use of up to 4096 virtual lans. When VXLAN was created, the engineers
went bat shit crazy. They allow you to use up to 16,777,216 different VLANS! You’ll never
have a need for this many, but it is a nice data point to know. VXLAN therefore allows us to
make use of an increased VLAN address space, multi tenancy, and connectivity across
disparate data centers. If you are familiar with general IP and data networking, you’ll know
that we are able to get those 4096 VLANs because of the fact that the vlan id field in an
ethernet frame has a 12-bit field specifying the VLAN to which the frame belongs. We
apply 2 to the power of 12, giving us 4096. The VXLAN Identifier space is 24 bits! With this
knowledge, we apply 2 to the power of 24 and that is how we get that 16 million plus
number. A VLAN identifier gets stuffed right into the ethernet frame. The VXLAN identifier
differs in that it makes use the the Internet Protocol as the transport medium, specifically a
UDP packet.
UCS Management
UCS Manager is a graphical user interface written in Java that you can use to manage all
aspects of your Cisco UCS system. If you had a need for a Multi-Domain Cisco UCS
environment, then you would make use of something called Cisco UCS Central – but that
is much less common in the field. By default, you will have the role of Server Equipment
Administrator which provides read and write access to physical server operations and just
read access to other parts of the system. Most configuration is handled via service proflies,
which contain hardware identifiers, firmware, state, configuration, and connectivity
characteristics. If a GUI is not your thing, you can still manage UCS from the command
line by connected via SSH to the cluster IP address of the UCS Fabric Interconnect
System. Another option is Cisco UCS Director, good for a single FlexPod. A good tip when
managing the Fabric Interconnect is leaving the switching mode alone. Changing it is very
disruptive to the system.
And POOF! Welcome to a fully virtualized LAMP stack dedicated to WordPress Development.
This first use case showed a full example of finding a suitable VMware pre built VMware
appliance file, and getting it up and running so a Web Developer can inspect and dissect
every aspect of the LAMP stack, all right from the comfort of your humble Windows
Laptop. Incredibly cool, right!?
4. Product Demos
With VMware Workstation, Systems Engineers can now hop on a plane with their laptop
and WMware Workstation with entire virtual networks and perform application
demonstrations at potential client sites. Consider a web based application that has a very
specific set of requirements such as a client, a database, and a web server all on different
machines that interact with each other. How could a Systems Engineer demonstrate that
with only a laptop? With VMware Workstation, they can do so easily. Multiple virtual
machines could be created ahead of time, configured for the multi tier application, and
simply brought online when it comes time for the product demo. No matter what application
you might need to demonstrate, VMware Workstation is a fantastic solution.
5. vSphere Staging
vSphere is the enterprise infrastructure solution for running virtualized solutions for all
kinds of customers. If a company is considering deploying some new virtual appliances,
you can first get these from the VMware Virtual Appliance Marketplace and load them into
VMware Workstation. Once you have them running in Workstation, you can put stress
tests on them, modify and configure various options before moving these virtual appliances
into the vSphere production infrastructure. Another use case with vSphere is to move
virtual machines out of production and onto Workstation in a fully virtualized private
network for various configuration updates and changes before moving them back to
vSphere production. This makes VMware Workstation a great tool for VMware
administrators to run local copies of production appliances in an isolated testing
environment, all on their own laptop.
6. Software Development
If you’re a software developer, you know the importance of having the correct environment
to both build and test your application on. You can’t build a web application on Microsoft
IIS for example, and then when you push it to the production LAMP stack and have it fail.
Management is not going to be fond of the, “Well it works on may machine” excuse. With
VMware Workstation, software developers can test their application against multiple
operating systems as well as take snapshots of their virtual machines both before and after
installation of their application to see how it affects the operating system and so on. In
many ways, it gives the developer an unlimited virtual lab environment for which to test
their applications to minimize potential platform bugs or errors before moving to a
production environment.
7. Browser Testing
With the modern world of JavaScript applications that run in the Browser, testing has
become more important than ever across all of the popular web browsers. Even if you
have all browsers installed on your host machine, what about different versions of that
browser? In fact, sometimes you will see a web application work fine using Google
Chrome on Windows 7, but you find a bug using the same exact browser but on Linux or
OSX. When you consider that you’ll need to test multiple browsers and versions on
multiple operating systems, it simply becomes too much to do on a host machine.
Microsoft even offers their own virtual machines for browser testing so you can test the
Microsoft Edge browser in addition to versions of IE8 through IE11 using Microsoft
approved virtual machines.
The install step itself will take a little bit of time. Five or Ten minutes should be enough for
it to complete, depending on the processing power of the computer you are using to run
VMware on. Once it completes, you will be ready to log in to your new Ubuntu Desktop!
Log in to Ubuntu Desktop!
Once you log in, the first thing we should probably do is set a screen size so that all of the
icons and layout look nice. We do this under Settings, Displays, then Resolution. We
chose 1280 by 1024 for this demonstration.
Test out some software!
The Firefox Browser comes installed on Ubuntu Desktop. When we launch it, we can see
that our virtual machine has network access right away. We can even browse to some
different websites if we like. Let’s have a visit to our homepage.
Awesome! You now have a fully functioning Ubuntu Desktop to work with.
Once we have the terminal launched, we can check to see if git is installed by simply
typing git at the terminal. As you can see when we type this, we get the following
message: The program git is currently not installed. You can install it by typing: sudo apt
install git. Ok sounds good, we will do just that. This step will also require that you provide
the password you used to initially set up your Ubuntu install.
Once you provide the password, Ubuntu will reach out to it’s update servers, download,
and install the package for you.
With git now installed, we should be able to simply type git at the terminal and see a list of
all the things we can do with this version control software. As we can see here, this did
work great as we can see all of the associated git commands listed out such as clone, init,
add, mv, reset, rm brach, checkout, commit, diff, merge, rebase, tag, fetch, etc…
When creating guest operating systems in your VMware Workstation setup, it’s
a good idea to make sure that VMware Tools are installed. To be clear,
VMware tools is a software package that installs on the guest OS, not the host.
VMware tools does many helpful things. One of the nicest things it does is to
provide a seamless mouse experience between the host and guest operating
system. What we mean by this is as you move your mouse between your host
and then into the guest OS, you may experience times when the mouse
appears to freeze inside VMware and you essentially lose your mouse so to
speak. VMware tools prevents mouse lock by synchronizing mouse input
between the Host and Guest OS. In addition to this nice feature, VMware tools
improves video performance in the guest OS, enables file sharing between
guest and host, provides Unity mode, as well as Guest OS shutdown and
restart options. Let’s install VMware tools on our Ubuntu Desktop now.
Select VM – Install VMware Tools
2 LOGFILE=/var/log/vmware-install.log
3 dir=`dirname $0`
note:The -d switch instructs the command to run and accept all defaults as it progresses.
This should be fine.
Reboot Ubuntu once the prior step is complete.
In order to complete the installation of VMware tools in Ubuntu Linux, we need to reboot
the virtual machine. Do this at the terminal by simply typing sudo reboot.
Confirm VMware Tools is running at the terminal
Once the virtual machine reboots, go back to the terminal so we can check the status of
VMware tools. By typing service vmware-tools status we can see some output that
confirms it is active and running on our machine.
After this, be sure to reboot the guest via sudo reboot before continuing. Now we are
ready to install VMware tools on Ubuntu using the terminal. Simply type sudo apt-get
install open-vm-tools to complete the process. Once this is done we can confirm the
service is running with service open-vm-tools status. We see the service is loaded,
enabled, active, and running.
Paying attention to this important message, let’s have a look at the Vagrantfile itself.
The Vagrantfile
# -*- mode: ruby -*-
# vi: set ft=ruby :
# Every Vagrant development environment requires a box. You can search for
# boxes at https://atlas.hashicorp.com/search.
config.vm.box = "hashicorp/precise32"
# Disable automatic box update checking. If you disable this, then
# boxes will only be checked for updates when the user runs
# `vagrant box outdated`. This is not recommended.
# config.vm.box_check_update = false
# Define a Vagrant Push strategy for pushing to Atlas. Other push strategies
# such as FTP and Heroku are also available. See the documentation at
# https://docs.vagrantup.com/v2/push/atlas.html for more information.
# config.push.define "atlas" do |push|
# push.app = "YOUR_ATLAS_USERNAME/YOUR_APPLICATION_NAME"
# end
It will take a little bit of time for the image that contains Ubuntu Precise Linux to download.
What Vagrant is doing in this step is to create and launch a virtual machine running Ubuntu
Linux. Everything is configured for you automatically, including SSH. When the process
completes, you can SSH with the vagrant ssh command from the Guest into the Virtual
Machine. Let’s try that now.
vagrant ssh
You are now logged into the Ubuntu Precise Linux Virtual Machine via SSH from the Host
machine. Notice the new prompt of vagrant@precise32:~$. Go ahead and type a few
linux commands to test things out.
uname -a
The output of this command is Linux precise32 3.2.0-23-generic-pae #36-Ubuntu SMP Tue
Apr 10 22:19:09 UTC 2012 i686 i686 i386 GNU/Linux, so we know that the VM is working
perfectly. Finally, we can log out of the SSH session, and just list and confirm running
virtual machines via VirtualBox. We can do that with the vboxmanage list
runningvms command like so.
vboxmanage list runningvms
Awesome! Well how about that?! A fully functional Ubuntu Virtual Machine that was
provisioned with just a handful of commands in Vagrant.
3 vb.gui = true
6 vb.memory = "1024"
7 end
With this modification to the Vagrantfile, we can now reload the virtual machine with
the vagrant reload command.
vagrant reload
During this reload of the virtual machine, the newly booting VM will launch it’s own GUI you
can log into without the need for SSH. The user name and password are both vagrant.
From here, we can interact with the virtual machine using all the same commands as if we
were connected via SSH. One final way for us to prove this Virtual Machine is in fact alive
and well is to launch the Virtualbox GUI itself. To do so, just type virtualbox at the
terminal. Notice a new GUI launches that gives you information about the running virtual
machine. We can see the name, operating system, base memory, boot order, acceleration,
video memory, IDE controller and more.
Synced Folders
A great feature of creating virtual machines with Vagrant is that of automatic file sharing
between host and guest operating systems. This is better known as synced folders.
The host operating system is the OS of the host machine. This is what the type 2
hypervisor runs on top of. These demonstrations are making use of VirtualBox, however
many other providers are available with VMware being a popular choice. Operating
systems that run in the hypervisor are referred to as Guests. Let’s check out a quick
demonstration to prove that file sharing is already enabled.
To begin, we will create a new file on our host operating system
named my_shared_file via the simple touch command. A quick ls shows that the file is
now created.
With the file now created on the host OS, we can use nano my_shared_file to add some
text to the file. Like the file says, we will be able to access this file on the guest OS too as
Vagrant sets up synced folders right away. By default, the folder which contains the
Vagrantfile on the host will be shared with the /vagrant folder on the guest.
From our host, we will now SSH into the guest via vagrant ssh. Once logged into our
guest OS, we change to the /vagrant directory via cd /vagrant, and then list it’s contents
with ls. We see the file is there automatically! To prove it is the same file, we can view it’s
contents with the cat command and the text is in fact the same that we created on the
host.
The great thing about shared files, or synced folders, is that it makes it easy to work on the
guest with the editors and tools of your choice. All testing happens on the guest, which is a
closer replication of a production environment.
When we are ready to bring this VM back online, we can make use of vagrant resumelike
so.
The key takeaway when using vagrant suspend and vagrant resume, is that this
approach saves the state of the virtual machine.
The takeaway with vagrant halt and vagrant up is that this approach conserves
resources on the host, but the guest will take longer to boot after a halt. So now we know
the difference between using each approach.
After destroying the VM, we can see that there are in fact no running virtual machines
when we check the status from both Vagrant and VirtualBox. Now, consider that this virtual
machine is entirely deleted and gone. What we still have however, is the Vagrantfile. It is
still in that Ubuntu directory we had created on the host machine. With that file, it only
takes us a few minutes to spin up a whole new virtual machine. Let’s see.
We have an entirely brand new virtual machine running now. Notice the
Check that out!
unique identifier on this new VM, it is “ubuntu_default_1470073198181_65287” {580d88af-
93b4-4c90-81b8-3fa1bff04b84}. This is completely different than the original VM we were
working on which was “ubuntu_default_1469830649698_22953” {4c253c3e-de65-4285-
82b5-3a2a84d9f69d}. So the takeaway from this is that vagrant suspend and vagrant
halt are ways of stopping the VM, which can then be resumed. If you run a vagrant
destroy however, you are entirely wiping out the VM and associated files with that VM.
This is like manually deleting a virtual machine in the VMware or VirtualBox gui. With our
Vagrantfile however, it is quick and painless to spin up a new virtual machine right
away. During your time working with Vagrant, you will find which approach works best for
you with regard to stopping, resuming, destroying, and creating virtual machines.
vagrant destroy stops and deletes all traces of the vagrant machine
2 config.vm.box = "hashicorp/precise32"
4 end