<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Zend Developer Zone</title>
	<atom:link href="https://devzone.zend.com/feed/" rel="self" type="application/rss+xml" />
	<link>https://devzone.zend.com</link>
	<description>Where the ElePHPants come to learn</description>
	<lastBuildDate>Thu, 05 Oct 2017 14:10:06 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=5.0.3</generator>
	<item>
		<title>PHP 7.2: Add Extension By Name</title>
		<link>https://devzone.zend.com/7630/php-7-2-add-extension-name/</link>
		<comments>https://devzone.zend.com/7630/php-7-2-add-extension-name/#respond</comments>
		<pubDate>Thu, 29 Jun 2017 18:36:37 +0000</pubDate>
		<dc:creator><![CDATA[Cal Evans]]></dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[extensions]]></category>
		<category><![CDATA[php7.2]]></category>

		<guid isPermaLink="false">https://devzone.zend.com/?p=7630</guid>
		<description><![CDATA[<p>I don't know if you've been keeping up, but there's not a lot of new coming down the pipe in PHP 7.2.  Yeah, there is a good list of things that are being deprecated, and a change to allow for type widening, but compared to PHP 7.0 and PHP 7.2, PHP 7.2 is positively a yawner. This makes writing articles about the new hotness coming down the pipe a bit difficult.</p>
<p>The post <a rel="nofollow" href="https://devzone.zend.com/7630/php-7-2-add-extension-name/">PHP 7.2: Add Extension By Name</a> appeared first on <a rel="nofollow" href="https://devzone.zend.com">Zend Developer Zone</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>I don&#8217;t know if you&#8217;ve been keeping up, but there&#8217;s not a lot of new coming down the pipe in PHP 7.2.  Yeah, there is a good <a href="https://devzone.zend.com/7628/deprecations-php-7-2/" target="_blank">list of things that are being deprecate</a>d, and a change to allow for type widening, but compared to PHP 7.0 and PHP 7.1, PHP 7.2 is positively a yawner. This makes writing articles about the new hotness coming down the pipe a bit difficult. Even so, there are a couple of things that are worth noting in PHP 7.2 One of them is <a href="https://wiki.php.net/rfc/load-ext-by-name" target="_blank">&#8220;PHP RFC: Allow loading extensions by name&#8221;</a>.</p>
<p>The way PHP handles loading extensions is absolutely fine, if you are a Linux system admin. Honestly, there was a time when most of us who managed PHP on a server were. The <code>extension=</code> lines in a php.ini require that you know the exact name of the extension. That name is different on Windows severs than on Linux servers. Even though the majority of PHP deployments are still on some variant of Unix, not all are.</p>
<p>So, to resolve this issue for the sake of the sanity of DevOps teams everywhere, PHP 7.2 will allow extensions to be loaded by name in addition to file name.</p>
<p>So now, all of these will be acceptable:</p>
<p></p><pre class="crayon-plain-tag">extension=bz2
extension=php_bz2.dll
extension=bz2.so
extension=bz2.sl</pre><p> </p>
<p>The last one being the proper file name on an HP-UX system.</p>
<p>This also means that there is one less difference between Windows and *nix php.ii files. Those of us who swap between the two will be greatly relieved.</p>
<p>&nbsp;</p>
<p>The post <a rel="nofollow" href="https://devzone.zend.com/7630/php-7-2-add-extension-name/">PHP 7.2: Add Extension By Name</a> appeared first on <a rel="nofollow" href="https://devzone.zend.com">Zend Developer Zone</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://devzone.zend.com/7630/php-7-2-add-extension-name/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Deprecations in PHP 7.2</title>
		<link>https://devzone.zend.com/7628/deprecations-php-7-2/</link>
		<comments>https://devzone.zend.com/7628/deprecations-php-7-2/#comments</comments>
		<pubDate>Tue, 27 Jun 2017 15:41:29 +0000</pubDate>
		<dc:creator><![CDATA[Cal Evans]]></dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[deprecation]]></category>
		<category><![CDATA[php72]]></category>
		<category><![CDATA[wave bye-bye to your favorite functions]]></category>

		<guid isPermaLink="false">https://devzone.zend.com/?p=7628</guid>
		<description><![CDATA[<blockquote><p>
The only constant is change.<br />
- Heraclitus of Ephesus
</p></blockquote>
<p>PHP is a living language and as such, as some things are added, others are removed. Click on inside to find out what is being flagged to go away in PHP 7.2</p>
<p>The post <a rel="nofollow" href="https://devzone.zend.com/7628/deprecations-php-7-2/">Deprecations in PHP 7.2</a> appeared first on <a rel="nofollow" href="https://devzone.zend.com">Zend Developer Zone</a>.</p>
]]></description>
				<content:encoded><![CDATA[<blockquote><p>The only constant is change.<br />
&#8211; Heraclitus of Ephesus</p></blockquote>
<p>PHP is a living language and as such, as some things are added, others are removed. Since PHP adheres to the best practice of Semantic Versioning, nothing will be going away in PHP 7.2, but some things will be marked as &#8220;Deprecated&#8221; so that developers can start removing them from their code and finding better ways to get the job done.</p>
<p>PHP 7.2 brings us a new list of things that will be eventually going away. The complete list, as well as explinations and voting can be found at <a href="https://wiki.php.net/rfc/deprecations_php_7_2" target="_blank" rel="noopener">&#8220;PHP RFC: Deprecations for PHP 7.2&#8221;</a> Here&#8217;s the rundown.</p>
<ul>
<li class="level1">
<div class="li"><code>__autoload</code></div>
</li>
<li class="level1">
<div class="li"><code>$php_errormsg</code></div>
</li>
<li class="level1">
<div class="li"><code>create_function()</code></div>
</li>
<li class="level1">
<div class="li"><code>mbstring.func_overload</code></div>
</li>
<li class="level1">
<div class="li"><code>(unset)</code> cast</div>
</li>
<li class="level1">
<div class="li"><code>parse_str()</code> without second argument</div>
</li>
<li class="level1">
<div class="li"><code>gmp_random()</code></div>
</li>
<li class="level1">
<div class="li"><code>each()</code></div>
</li>
<li class="level1">
<div class="li"><code>assert()</code> with string argument</div>
</li>
<li class="level1">
<div class="li"><code>$errcontext</code> argument of error handler</div>
</li>
</ul>
<p>Of all the ones being voted on, only <code>each()</code> seems like it may not pass. The rest are all unanimous or with one or two no votes.</p>
<p>So it&#8217;s time to fire up your favorite IDE (or grep) and start looking for these. Again, they will not go away when PHP 7.2 is released. However, you are being put on notice that they will go away when 8 is released so you might as well identify them and start working on a fix.</p>
<p>&nbsp;</p>
<p>The post <a rel="nofollow" href="https://devzone.zend.com/7628/deprecations-php-7-2/">Deprecations in PHP 7.2</a> appeared first on <a rel="nofollow" href="https://devzone.zend.com">Zend Developer Zone</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://devzone.zend.com/7628/deprecations-php-7-2/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>June 2017 PHP Community (coffee) Cup of Service winner</title>
		<link>https://devzone.zend.com/7619/june-2017-php-community-coffee-cup-service-winner/</link>
		<comments>https://devzone.zend.com/7619/june-2017-php-community-coffee-cup-service-winner/#respond</comments>
		<pubDate>Fri, 16 Jun 2017 12:00:00 +0000</pubDate>
		<dc:creator><![CDATA[Cal Evans]]></dc:creator>
				<category><![CDATA[Community]]></category>
		<category><![CDATA[php community]]></category>
		<category><![CDATA[sara golemon]]></category>

		<guid isPermaLink="false">https://devzone.zend.com/?p=7619</guid>
		<description><![CDATA[<p>It is time for the June 2017 PHP Community (coffee) Cup of Service award. This month it goes to someone who has been giving to PHP for more than 15 years, Ms. Sara Golemon. Sara: Is a regular speaker at PHP conferences worldwide An active core contributor One of the release managers of PHP 7.2 Please join us here at... <a href="https://devzone.zend.com/7619/june-2017-php-community-coffee-cup-service-winner/">Read more &#187;</a></p>
<p>The post <a rel="nofollow" href="https://devzone.zend.com/7619/june-2017-php-community-coffee-cup-service-winner/">June 2017 PHP Community (coffee) Cup of Service winner</a> appeared first on <a rel="nofollow" href="https://devzone.zend.com">Zend Developer Zone</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>It is time for the June 2017 PHP Community (coffee) Cup of Service award. This month it goes to someone who has been giving to PHP for more than 15 years, Ms. Sara Golemon. </p>
<p><img src="https://devzone.zend.com/wp-content/uploads/2017/06/14746437751_d1bc139d9a_z.jpg" alt="" width="640" height="640" class="aligncenter size-full wp-image-7620" /></p>
<p>Sara:</p>
<ul>
<li>Is a regular speaker at PHP conferences worldwide</li>
<li>An active core contributor</li>
<li>One of the release managers of PHP 7.2</li>
</ul>
<p>Please join us here at Rogue Wave in saying thank you to Sara for her more than fifteen years of service to PHP and the PHP community.</p>
<p>Photo Credit: <a href="https://www.flickr.com/photos/akrabat/14746437751/in/photolist-ot6mbK-fkFHHP-dYsyzx-dYntAU-79Xtke-77Bo9c-77Fijh-6Wzn4D-6utxck-6r67mu-6qRjwr-6a2Eme-645pFa-649CvJ-5Fe2Rf-5F9CMK-5tXbz1-5tSFPH-5nkhmg-5nnUQC-5ngGrG-5ngFSs-5naXZ5-5n6G72-4Ny17R-4NCerU-4NCerq-4Ny16g-4Ny11x-4NCeiA-4NCe4N-4Nxe4M-4Egd1Q-4ze73o-4ovBW5-4nauaE-4mQsJV-4mQngz-4kumFe-3BBMm6-3BBMgc-3qG3HV-3oheqZ-3ogwJK-3om1DN-3okZdw-3kAQSr-3c36c7-3bXwak-3c2Wt7" target="_blank">Sara</a> by <a href="https://www.flickr.com/photos/akrabat/" target="_blank">Rob Allen</a> </p>
<p>The post <a rel="nofollow" href="https://devzone.zend.com/7619/june-2017-php-community-coffee-cup-service-winner/">June 2017 PHP Community (coffee) Cup of Service winner</a> appeared first on <a rel="nofollow" href="https://devzone.zend.com">Zend Developer Zone</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://devzone.zend.com/7619/june-2017-php-community-coffee-cup-service-winner/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>May 2017 PHP Community (coffee) Cup of Service winner</title>
		<link>https://devzone.zend.com/7585/may-2017-php-community-coffee-cup-service-winner/</link>
		<comments>https://devzone.zend.com/7585/may-2017-php-community-coffee-cup-service-winner/#respond</comments>
		<pubDate>Mon, 22 May 2017 16:21:24 +0000</pubDate>
		<dc:creator><![CDATA[Cal Evans]]></dc:creator>
				<category><![CDATA[Community]]></category>

		<guid isPermaLink="false">https://devzone.zend.com/?p=7585</guid>
		<description><![CDATA[<p>Since this is the very first &#8220;Michelangelo van Dam PHP Community (coffee) Cup of Service&#8221;, I spent a long time running through potential recipients. To set the tone for this award, I wanted someone who gives a lot back to our community. While there are a lot of worthy recipients that meet the criteria, the one that stood out to... <a href="https://devzone.zend.com/7585/may-2017-php-community-coffee-cup-service-winner/">Read more &#187;</a></p>
<p>The post <a rel="nofollow" href="https://devzone.zend.com/7585/may-2017-php-community-coffee-cup-service-winner/">May 2017 PHP Community (coffee) Cup of Service winner</a> appeared first on <a rel="nofollow" href="https://devzone.zend.com">Zend Developer Zone</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>Since this is the very first <a href="https://devzone.zend.com/the-honorary-michelangelo-van-dam-community-coffee-cup-of-service-award/" target="_blank">&#8220;Michelangelo van Dam PHP Community (coffee) Cup of Service&#8221;</a>, I spent a long time running through potential recipients. To set the tone for this award, I wanted someone who gives a lot back to our community. While there are a lot of worthy recipients that meet the criteria, the one that stood out to me was the man whose name is on the award. </p>
<p>it is our pleasure here at <a href="https://www.roguewave.com/" target="_blank">Rogue Wave</a> to present the very first &#8220;Michelangelo van Dam PHP Community (coffee) Cup of Service&#8221; to non other than the Don of the PHP Community, one of the PHP Ninja Turtles, Mr. Michelangelo van Dam himself.<br />
<img src="https://devzone.zend.com/wp-content/uploads/2017/05/dragonbe.jpg" alt="" width="400" height="400" class="aligncenter size-full wp-image-7594" /><br />
For those that are not aware of the contributions that Mike makes to our community.</p>
<ul>
<li>He is one of the founders of the PHPbenelux PHP community. It&#8217;s not a User Group, it is an entire community of more than 30 User Groups under one umbrella. Mike regularly travels to the groups under the PHPBenelux umbrella speaking and encouraging others.</li>
<li>He is one of the founders of the PHPBenelux Conference. </li>
<li>He is a regular speaker at PHP conferences worldwide.</li>
<li>Even when he isn&#8217;t speaking, he attends conferences on his own dime.</li>
</ul>
<p>For all that Michelangelo does for the PHP community, we award him the &#8220;Michelangelo van Dam PHP Community (coffee) Cup of Service&#8221;.</p>
<p>Thank you Michelangelo for all that you do for the PHP community. Keep up the good work.</p>
<p>The post <a rel="nofollow" href="https://devzone.zend.com/7585/may-2017-php-community-coffee-cup-service-winner/">May 2017 PHP Community (coffee) Cup of Service winner</a> appeared first on <a rel="nofollow" href="https://devzone.zend.com">Zend Developer Zone</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://devzone.zend.com/7585/may-2017-php-community-coffee-cup-service-winner/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Sharpen your knives</title>
		<link>https://devzone.zend.com/7574/sharpen-your-knives/</link>
		<comments>https://devzone.zend.com/7574/sharpen-your-knives/#respond</comments>
		<pubDate>Mon, 15 May 2017 12:57:23 +0000</pubDate>
		<dc:creator><![CDATA[Cal Evans]]></dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[conference]]></category>
		<category><![CDATA[developers]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[training]]></category>
		<category><![CDATA[ZendCon]]></category>

		<guid isPermaLink="false">https://devzone.zend.com/?p=7574</guid>
		<description><![CDATA[<p>As a manager, it is your responsibility to take care of, maintain, and improve the developers under your care. If you are not regularly investing in keeping their skills sharp, you are doing a disservice to your developers, to your project, and to your company. </p>
<p>The post <a rel="nofollow" href="https://devzone.zend.com/7574/sharpen-your-knives/">Sharpen your knives</a> appeared first on <a rel="nofollow" href="https://devzone.zend.com">Zend Developer Zone</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>I am the family cook. At least once a week, I spend two or more hours preparing a meal that takes my family  less than 15 minutes to eat. </p>
<p>When I get ready to dice meat or slice vegetables, I have my go-to knives for each job. I pull one from the draw carefully, rinse it, and then begin the task at hand. Most of the time, things are great, I finish and move on to the next task. There are times however, when I can tell after the first cut or so that my favorite knife is in need of a good sharpening. It’s not the knife’s fault, I know I have to maintain my equipment for it to perform for me. </p>
<p>It usually doesn’t take long. A couple of minutes on the steel or whetstone and we are back working to finish the meal.</p>
<p>Your developers are like knives. You, as the manager, have to invest in them to keep them sharp and usable. Just like I would never use a knife until it was hopelessly dull, and then throw it out; you don’t want to lose you investment in your developers by running them into the ground. You need to refresh them, renew them, inspire them.</p>
<p>There is no better way to reinvigorate a developer than to send them to a conference where they can sharpen their skills against the steel of other developers. They get inspired and educated through sessions presented. They reinvigorate by relaxing and sharing with friends new and old.</p>
<p>Sharpen the knives in your drawer. Send your developers to <a href="http://www.zendcon.com/" target="_blank">ZendCon 2017</a> and watch the difference in them when they return ready to tackle your projects with renewed vigor. </p>
<p>Or don’t. I’m sure their next employer will. ;)</p>
<p>The post <a rel="nofollow" href="https://devzone.zend.com/7574/sharpen-your-knives/">Sharpen your knives</a> appeared first on <a rel="nofollow" href="https://devzone.zend.com">Zend Developer Zone</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://devzone.zend.com/7574/sharpen-your-knives/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ZendCon 2017 Call for Papers is OPEN!</title>
		<link>https://devzone.zend.com/7559/zendcon-2017-call-papers-open/</link>
		<comments>https://devzone.zend.com/7559/zendcon-2017-call-papers-open/#respond</comments>
		<pubDate>Fri, 10 Mar 2017 16:52:02 +0000</pubDate>
		<dc:creator><![CDATA[Cal Evans]]></dc:creator>
				<category><![CDATA[Articles]]></category>

		<guid isPermaLink="false">https://devzone.zend.com/?p=7559</guid>
		<description><![CDATA[<p>For the five of you who are living under a rock and haven&#8217;t heard, the dates for ZendCon 2017 have been announced and the ZendCon 2017 Call for Papers is open. You will want to check out the complete Speaker&#8217;s package for all the details and awesomeness, but here are the highlights. Full conference pass (conference and tutorials) Lunch (conference... <a href="https://devzone.zend.com/7559/zendcon-2017-call-papers-open/">Read more &#187;</a></p>
<p>The post <a rel="nofollow" href="https://devzone.zend.com/7559/zendcon-2017-call-papers-open/">ZendCon 2017 Call for Papers is OPEN!</a> appeared first on <a rel="nofollow" href="https://devzone.zend.com">Zend Developer Zone</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>For the five of you who are living under a rock and haven&#8217;t heard, the dates for <a href="http://www.zendcon.com/" target="_blank">ZendCon 2017</a> have been announced and the <a href="http://cfp.zendcon.com" target="_blank">ZendCon 2017 Call for Papers</a> is open.<br />
<span id="more-7559"></span></p>
<p><a href="http://www.zendcon.com/" target="_blank"><img src="https://devzone.zend.com/wp-content/uploads/2017/03/Screen-Shot-2017-03-10-at-11.29.53-AM-1024x313.png" alt="" width="625" height="191" class="aligncenter size-large wp-image-7560" srcset="https://devzone.zend.com/wp-content/uploads/2017/03/Screen-Shot-2017-03-10-at-11.29.53-AM-1024x313.png 1024w, https://devzone.zend.com/wp-content/uploads/2017/03/Screen-Shot-2017-03-10-at-11.29.53-AM-150x46.png 150w, https://devzone.zend.com/wp-content/uploads/2017/03/Screen-Shot-2017-03-10-at-11.29.53-AM-300x92.png 300w, https://devzone.zend.com/wp-content/uploads/2017/03/Screen-Shot-2017-03-10-at-11.29.53-AM-768x235.png 768w, https://devzone.zend.com/wp-content/uploads/2017/03/Screen-Shot-2017-03-10-at-11.29.53-AM-624x191.png 624w" sizes="(max-width: 625px) 100vw, 625px" /></a></p>
<p>You will want to check out the complete <a href="http://cfp.zendcon.com/package" target="_blank">Speaker&#8217;s package</a> for all the details and awesomeness, but here are the highlights.</p>
<ul>
<li>Full conference pass (conference and tutorials)</li>
<li>Lunch (conference days only), receptions, and activities included in a full conference pass</li>
<li>Round-trip airfare (must be arranged through Rogue Wave Software)</li>
<li>2 complimentary hotel nights (must be arranged through Rogue Wave Software)</li>
<li>2 days of hanging out with the best and brightest in the PHP community&#8230;and also me!
<li>VEGAS!</li>
</ul>
<p>(Ok, I added those last two.) :)</p>
<p>Join us in Vegas this October and be a part of one of the largest gatherings of the PHP community. <a href="http://cfp.zendcon.com/" target="_blank">Submit your talk to ZendCon 2017 today</a>. (Submit at least 2 more tomorrow too!)</p>
<p>The post <a rel="nofollow" href="https://devzone.zend.com/7559/zendcon-2017-call-papers-open/">ZendCon 2017 Call for Papers is OPEN!</a> appeared first on <a rel="nofollow" href="https://devzone.zend.com">Zend Developer Zone</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://devzone.zend.com/7559/zendcon-2017-call-papers-open/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Scrape Screens with zend-dom</title>
		<link>https://devzone.zend.com/7552/scrape-screens-zend-dom/</link>
		<comments>https://devzone.zend.com/7552/scrape-screens-zend-dom/#respond</comments>
		<pubDate>Wed, 01 Mar 2017 16:36:33 +0000</pubDate>
		<dc:creator><![CDATA[Matthew Weier O'Phinney]]></dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Zend Framework]]></category>

		<guid isPermaLink="false">https://devzone.zend.com/?p=7552</guid>
		<description><![CDATA[<p>Even in this day-and-age of readily available APIs and RSS/Atom feeds, many sites offer none of them. How do you get at the data in those cases? Through the ancient internet art of screen scraping. The problem then becomes: how do you get at the data you need in a pile of HTML soup? You could use regular expressions or... <a href="https://devzone.zend.com/7552/scrape-screens-zend-dom/">Read more &#187;</a></p>
<p>The post <a rel="nofollow" href="https://devzone.zend.com/7552/scrape-screens-zend-dom/">Scrape Screens with zend-dom</a> appeared first on <a rel="nofollow" href="https://devzone.zend.com">Zend Developer Zone</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>Even in this day-and-age of readily available APIs and RSS/Atom feeds, many sites offer none of them. How do you get at the data in those cases? Through the ancient internet art of screen scraping.</p>
<p>The problem then becomes: how do you get at the data you need in a pile of HTML soup? You could use regular expressions or any of the various string functions in PHP. All of these are easily subject to error, though, and often require some convoluted code to get at the data of interest.</p>
<p>Alternately, you could treat the HTML as XML, and use the <a href="http://php.net/dom">DOM extension</a>, which is typically built-in to PHP. Doing so, however, requires more than a passing familiarity with <a href="https://en.wikipedia.org/wiki/XPath">XPath</a>, which is something of a black art.</p>
<p>If you use JavaScript libraries or write CSS fairly often, you may be familiar with CSS selectors, which allow you to target either specific nodes or groups of nodes within an HTML document. These are generally rather intuitive:</p>
<pre><code>jQuery('section.slide h2').each(function (node) {
  alert(node.textContent);
});</code></pre>
<p>What if you could do that with PHP?</p>
<h2>Introducing zend-dom</h2>
<p><a href="https://docs.zendframework.com/zend-dom/">zend-dom</a> provides CSS selector capabilities for PHP, via the <code>Zend\Dom\Query</code> class, including:</p>
<ul>
<li>element types (<code>h2</code>, <code>span</code>, etc.)</li>
<li>class attributes (<code>.error</code>, <code>.next</code>, etc.)</li>
<li>element identifiers (<code>#nav</code>, <code>#main</code>, etc.)</li>
<li>arbitrary element attributes (<code>div[onclick=&quot;foo&quot;]</code>), including word matches (<code>div[role~=&quot;navigation&quot;]</code>) and substring matches (<code>div[role*=&quot;complement&quot;]</code>)</li>
<li>descendents (<code>div .foo span</code>)</li>
</ul>
<p>While it does not implement the full spectrum of CSS selectors, it does provide enough to generally allow you to get at the information you need within a page.</p>
<h2>Example: retrieving a navigation list</h2>
<p>As an example, let&#8217;s fetch the navigation list from the <code>Zend\Dom\Query</code> documentation page itself:</p>
<pre><code>use Zend\Dom\Query;

$html = file_get_contents('https://docs.zendframework.com/zend-dom/query/');
$query = new Query($html);
$results = $query-&gt;execute('ul.bs-sidenav li a');

printf("Received %d results:\n", count($results));
foreach ($results as $result) {
    printf("- [%s](%s)\n", $result-&gt;getAttribute('href'), $result-&gt;textContent);
}</code></pre>
<p>The above queries for <code>ul.bs-sidenav li a</code> &mdash; in other words, all links within list items of the sidenav unordered list.</p>
<p>When you <code>execute()</code> a query, you are returned a <code>Zend\Dom\NodeList</code> instance, which decorates a <a href="http://php.net/class.domnodelist">DOMNodeList</a> in order to provide features such as <code>Countable</code>, and access to the original query and document. In the example above, we <code>count()</code> the results, and then loop over them.</p>
<p>Each item in the list is a <a href="http://php.net/class.domnode">DOMNode</a>, giving you access to any attributes, the text content, and any child elements. In our case, we access the <code>href</code> attribute (the link target), and report the text content (the link text).</p>
<p>The results are:</p>
<pre><code>Received 3 results:
- [#querying-html-and-xml-documents](Querying HTML and XML Documents)
- [#theory-of-operation](Theory of Operation)
- [#methods-available](Methods Available)</code></pre>
<h2>Other uses</h2>
<p>Another use case is for <em>testing</em>. When you have classes that return HTML, or if you want to execute requests and test the generated output, you often don&#8217;t want to test <em>exact</em> contents, but rather look for specific data or fragments within the document.</p>
<p>We provide these capabilities for <a href="https://docs.zendframework.com/zend-mvc/">zend-mvc</a> applications via the <a href="https://docs.zendframework.com/zend-test/">zend-test component</a>, which provides a number of <a href="https://docs.zendframework.com/zend-test/assertions/#css-selector-assertions">CSS selector assertions</a> for use in querying the content returned in your MVC responses. Having these capabilities allows testing for dynamic content as well as static content, providing a number of vectors for ensuring application quality.</p>
<h2>Start scraping!</h2>
<p>While this post was rather brief, we hope you can appreciate the powerful capabilities of this component! We have used this functionality in a variety of ways, from testing applications to creating feeds based on content differences in web pages, to finding and retrieving image URIs from pages.</p>
<p>Get more information from the <a href="https://docs.zendframework.com/zend-dom/">zend-dom documentation</a>.</p>
<blockquote>
<p>This article originally appeared on the Zend Framework blog at <a href="https://framework.zend.com/blog/2017-02-28-zend-dom.html">https://framework.zend.com/blog/2017-02-28-zend-dom.html</a>.</p>
</blockquote>
<p>The post <a rel="nofollow" href="https://devzone.zend.com/7552/scrape-screens-zend-dom/">Scrape Screens with zend-dom</a> appeared first on <a rel="nofollow" href="https://devzone.zend.com">Zend Developer Zone</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://devzone.zend.com/7552/scrape-screens-zend-dom/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>zend-config For All Your Configuration Needs</title>
		<link>https://devzone.zend.com/7549/zend-config-configuration-needs/</link>
		<comments>https://devzone.zend.com/7549/zend-config-configuration-needs/#respond</comments>
		<pubDate>Wed, 22 Feb 2017 16:18:52 +0000</pubDate>
		<dc:creator><![CDATA[Matthew Weier O'Phinney]]></dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Zend Framework]]></category>

		<guid isPermaLink="false">https://devzone.zend.com/?p=7549</guid>
		<description><![CDATA[<p>Different applications and frameworks have different opinions about how configuration should be created. Some prefer XML, others YAML, some like JSON, others like INI, and some even stick to the JavaProperties format; in Zend Framework, we tend to prefer PHP arrays, as each of the other formats essentially get compiled to PHP arrays eventually anyways. At heart, though, we like... <a href="https://devzone.zend.com/7549/zend-config-configuration-needs/">Read more &#187;</a></p>
<p>The post <a rel="nofollow" href="https://devzone.zend.com/7549/zend-config-configuration-needs/">zend-config For All Your Configuration Needs</a> appeared first on <a rel="nofollow" href="https://devzone.zend.com">Zend Developer Zone</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>Different applications and frameworks have different opinions about how configuration should be created. Some prefer XML, others YAML, some like JSON, others like INI, and some even stick to the JavaProperties format; in Zend Framework, we tend to prefer PHP arrays, as each of the other formats essentially get compiled to PHP arrays eventually anyways.</p>
<p>At heart, though, we like to support developer needs, whatever they may be, and, as such, our <a href="https://docs.zendframework.com/zend-config/">zend-config component</a> provides ways of working with a variety of configuration formats.</p>
<h2>Installation</h2>
<p>zend-config is installable via Composer:</p>
<pre><code>$ composer require zendframework/zend-config</code></pre>
<p>The component has two dependencies:</p>
<ul>
<li><a href="https://docs.zendframework.com/zend-stdlib/">zend-stdlib</a>, which provides some capabilities around configuration merging.</li>
<li><a href="https://github.com/php-fig/container">psr/container</a>, to allow reader and writer plugin support for the configuration factory.</li>
</ul>
<blockquote>
<h3>Latest version</h3>
<p>This article covers the most recently released version of zend-config, 3.1.0, which contains a number of features such as PSR-11 support that were not previously available. If you are using Zend Framework, you should be able to safely provide the constraint <code>^2.6 || ^3.1</code>, as the primary APIs remain the same.</p>
</blockquote>
<h2>Retrieving configuration</h2>
<p>Once you&#8217;ve installed zend-config, you can start using it to retrieve and access configuration files. The simplest way is to use <code>Zend\Config\Factory</code>, which provides tools for loading configuration from a variety of formats, as well as capabilities for merging.</p>
<p>If you&#8217;re just pulling in a single file, use <code>Factory::fromFile()</code>:</p>
<pre><code>use Zend\Config\Factory;

$config = Factory::fromFile($path);</code></pre>
<p>Far more interesting is to use multiple files, which you can do via <code>Factory::fromFiles()</code>. When you do, they are merged into a single configuration, in the order in which they are provided to the factory. This is particularly interesting using <code>glob()</code>:</p>
<pre><code>use Zend\Config\Factory;

$config = Factory::fromFiles(glob('config/autoload/*.*'));</code></pre>
<p>What&#8217;s particularly interesting about this is that it supports a variety of formats:</p>
<ul>
<li>PHP files returning arrays (<code>.php</code> extension)</li>
<li>INI files (<code>.ini</code> extension)</li>
<li>JSON files (<code>.json</code> extension)</li>
<li>XML files (using PHP&#8217;s <code>XMLReader</code>; <code>.xml</code> extension)</li>
<li>YAML files (using ext/yaml, installable via PECL; <code>.yaml</code> extension)</li>
<li>JavaProperties files (<code>.javaproperties</code> extension)</li>
</ul>
<p>This means that you can choose the configuration format you prefer, or mix-and-match multiple formats, if you need to combine configuration from multiple libraries!</p>
<h2>Configuration objects</h2>
<p>By default, <code>Zend\Config\Factory</code> will return PHP arrays for the merged configuration. Some dependency injection containers do not support arrays as services, however; moreover, you may want to pass some sort of structured object instead of a plain array when injecting dependencies.</p>
<p>As such, you can pass a second, optional argument to each of <code>fromFile()</code> and <code>fromFiles()</code>, a boolean flag. When <code>true</code>, it will return a <code>Zend\Config\Config</code> instance, which implements <code>Countable</code>, <code>Iterator</code>, and <code>ArrayAccess</code>, allowing it to look and act like an array.</p>
<p>What is the benefit?</p>
<p>First, it provides property overloading to each configuration key:</p>
<pre><code>$debug = $config-&gt;debug ?: false;</code></pre>
<p>Second, it offers a convenience method, <code>get()</code>, which allows you to specify a default value to return if the value is not found:</p>
<pre><code>$debug = $config-&gt;get('debug', false); // Return false if not found</code></pre>
<p>This is largely obviated by the <code>?:</code> ternary shortcut in modern PHP versions, but very useful when <em>mocking</em> in your tests.</p>
<p>Third, nested sets are also returned as <code>Config</code> instances, which gives you the ability to use the above <code>get()</code> method on a nested item:</p>
<pre><code>if (isset($config-&gt;expressive)) {
    $config = $config-&gt;get('expressive'); // same API!
}</code></pre>
<p>Fourth, you can mark the <code>Config</code> instance as immutable! By default, it acts just like array configuration, which is, of course, mutable. However, this can be problematic when you use configuration as a service, because, unlike an array, a <code>Config</code> instance is passed by reference, and changes to values would then propagate to any other services that depend on the configuration.</p>
<p>Ideally, you wouldn&#8217;t be changing any values in the instance, but <code>Zend\Config\Config</code> can enforce that for you:</p>
<pre><code>$config-&gt;setReadOnly(); // Now immutable!</code></pre>
<p>Further, calling this will mark nested <code>Config</code> instances as read-only as well, ensuring data integrity for the entire configuration tree.</p>
<blockquote>
<h3>Read-only by default!</h3>
<p>One thing to note: by default, <code>Config</code> instances are read-only! The constructor accepts an optional, second argument, a flag indicating whether or not the instance allows modifications, and the value is <code>false</code> by default.  Whenever you use the <code>Factory</code> to create a <code>Config</code> instance, it never enables that flag, meaning that if you return a <code>Config</code> instance, it will be read-only.</p>
<p>If you want a mutable instance from a <code>Factory</code>, use the following construct:</p>
<pre><code>use Zend\Config\Config;
use Zend\Config\Factory;

$config = new Config(Factory::fromFiles($files), true);</code></pre>
</blockquote>
<h2>Including other configuration</h2>
<p>Most of the configuration reader plugins also support &quot;includes&quot;: directives within a configuration file that will include configuration from another file.  (JavaProperties is the only configuration format we support that does not have this functionality included.)</p>
<p>For instance:</p>
<ul>
<li>
<p>INI files can use the key <a href="mailto:code>@include</code">code>@include</code</a> to include another file relative to the current one; values are merged at the same level:</p>
<pre><code>webhost = 'www.example.com'
@include = 'database.ini'</code></pre>
</li>
<li>
<p>For XML files, you can use <a href="http://www.w3.org/TR/xinclude/">XInclude</a>:</p>
<pre><code>&lt;?xml version="1.0" encoding="utf-8"&gt;
&lt;config xmlns:xi="http://www.w3.org/2001/XInclude"&gt;
&lt;webhost&gt;www.example.com&lt;/webhost&gt;
&lt;xi:include href="database.xml"/&gt;
&lt;/config&gt;</code></pre>
</li>
<li>
<p>JSON files can use an <a href="mailto:code>@include</code">code>@include</code</a> key:</p>
<pre><code>{
"webhost": "www.example.com",
"@include": "database.json"
}</code></pre>
</li>
<li>
<p>YAML also uses the <a href="mailto:code>@include</code">code>@include</code</a> notation:</p>
<pre><code>webhost: www.example.com
@include: database.yaml</code></pre>
</li>
</ul>
<h2>Choose your own YAML</h2>
<p>Out-of-the-box we support the <a href="http://www.php.net/manual/en/book.yaml.php">YAML PECL extension</a> for our YAML support. However, we have made it possible to use alternate parsers, such as Spyc or the Symfony YAML component, by passing a callback to the reader&#8217;s constructor:</p>
<pre><code>use Symfony\Component\Yaml\Yaml as SymfonyYaml;
use Zend\Config\Reader\Yaml as YamlConfig;

$reader = new YamlConfig([SymfonfyYaml::class, 'parse']);
$config = $reader-&gt;fromFile('config.yaml');</code></pre>
<p>Of course, if you&#8217;re going to do that, you could just use the original library, right? But what if you want to mix YAML and other configuration with the <code>Factory</code> class?</p>
<p>There aer two ways to register new plugins. One is to create an instance and register it with the factory:</p>
<pre><code>use Symfony\Component\Yaml\Yaml as SymfonyYaml;
use Zend\Config\Factory;
use Zend\Config\Reader\Yaml as YamlConfig;

Factory::registerReader('yaml', new YamlConfig([SymfonyYaml::class, 'parse']));</code></pre>
<p>Alternately, you can provide an alternate reader plugin manager. You can do that by extending <code>Zend\Config\StandaloneReaderPluginManager</code>, which is a barebones PSR-11 container for use as a plugin manager:</p>
<pre><code>namespace Acme;

use Symfony\Component\Yaml\Yaml as SymfonyYaml;
use Zend\Config\Reader\Yaml as YamlConfig;
use Zend\Config\StandaloneReaderPluginManager;

class ReaderPluginManager extends StandaloneReaderPluginManager
{
    /**
     * @inheritDoc
     */
    public function has($plugin)
    {
        if (YamlConfig::class === $plugin
            || 'yaml' === strtolower($plugin)
        ) {
            return true;
        }

        return parent::has($plugin);
    }

    /**
     * @inheritDoc
     */
    public function get($plugin)
    {
        if (YamlConfig::class !== $plugin
            &amp;&amp; 'yaml' !== strtolower($plugin)
        ) {
            return parent::get($plugin);
        }

        return new YamlConfig([SymfonyYaml::class, 'parse']);
    }
}</code></pre>
<p>Then register this with the <code>Factory</code>:</p>
<pre><code>use Acme\ReaderPluginManager;
use Zend\Config\Factory;

Factory::setReaderPluginManager(new ReaderPluginManager());</code></pre>
<h2>Processing configuration</h2>
<p>zend-config also allows you to <em>process</em> a <code>Zend\Config\Config</code> instance and/or an individual value. Processors perform operations such as:</p>
<ul>
<li>substituting constant values within strings</li>
<li>filtering configuration data</li>
<li>replacing tokens within configuration</li>
<li>translating configuration values</li>
</ul>
<p>Why would you want to do any of these operations?</p>
<p>Consider this: deserialization of formats other than PHP cannot take into account PHP constant values or class names!</p>
<p>While this may work in PHP:</p>
<pre><code>return [
    Acme\Component::CONFIG_KEY =&gt; [
        'host' =&gt; Acme\Component::CONFIG_HOST,
        'dependencies' =&gt; [
            'factories' =&gt; [
                Acme\Middleware\Authorization::class =&gt; Acme\Middleware\AuthorizationFactory::class,
            ],
        ],
    ],
];</code></pre>
<p>The following JSON configuration would not:</p>
<pre><code>{
    "Acme\\Component::CONFIG_KEY": {
        "host": "Acme\\Component::CONFIG_HOST"
        "dependencies": {
            "factories": {
                "Acme\\Middleware\\Authorization::class": "Acme\\Middleware\\AuthorizationFactory::class"
            }
        }
    }
}</code></pre>
<p>Enter the <code>Constant</code> processor!</p>
<p>This processor looks for strings that match constant names, and replaces them with their values. Processors generally only work on the configuration <em>values</em>, but the <code>Constant</code> processor allows you to opt-in to processing the <em>keys</em> as well.</p>
<p>Since processing <em>modifies</em> the <code>Config</code> instance, you will need to manually create an instance, and then process it. Let&#8217;s look at that:</p>
<pre><code>use Acme\Component;
use Zend\Config\Config;
use Zend\Config\Factory;
use Zend\Config\Processor;

$config = new Config(Factory::fromFile('config.json'), true);
$processor = new Processor\Constant();
$processor-&gt;enableKeyProcessing();
$processor-&gt;process($config);
$config-&gt;setReadOnly();

var_export($config-&gt;{Component::CONFIG_KEY}-&gt;dependencies-&gt;factories);
// ['Acme\Middleware\Authorization' =&gt; 'Acme\Middleware\AuthorizationFactory']</code></pre>
<p>This is a really powerful feature, as it allows you to add more verifications and validations to your configuration files, regardless of the format you use.</p>
<blockquote>
<h3>In version 3.1.0 forward</h3>
<p>The ability to work with class constants and process keys was added only recently in the 3.1.0 version of zend-config.</p>
</blockquote>
<h2>Config all the things!</h2>
<p>This post covers the parsing features of zend-config, but does not even touch on another major capability: the ability to <em>write</em> configuration! We&#8217;ll leave that to another post.</p>
<p>In terms of configuration parsing, zend-config is simple, yet powerful. The ability to process a number of common configuration formats, utilize configuration includes, and process keys and values means you can highly customize your configuration process to suit your needs or integrate different configuration sources.</p>
<p>Get more information from the <a href="https://docs.zendframework.com/zend-config/">zend-config documentation</a>.</p>
<blockquote>
<p>This article originally appeared on the Zend Framework blog at <a href="https://framework.zend.com/blog/2017-02-22-zend-config.html">https://framework.zend.com/blog/2017-02-22-zend-config.html</a>.</p>
</blockquote>
<p>The post <a rel="nofollow" href="https://devzone.zend.com/7549/zend-config-configuration-needs/">zend-config For All Your Configuration Needs</a> appeared first on <a rel="nofollow" href="https://devzone.zend.com">Zend Developer Zone</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://devzone.zend.com/7549/zend-config-configuration-needs/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP and SQL Server for Linux</title>
		<link>https://devzone.zend.com/7545/php-sql-server-linux/</link>
		<comments>https://devzone.zend.com/7545/php-sql-server-linux/#respond</comments>
		<pubDate>Tue, 14 Feb 2017 21:28:15 +0000</pubDate>
		<dc:creator><![CDATA[Matthew Weier O'Phinney]]></dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Zend Framework]]></category>

		<guid isPermaLink="false">https://devzone.zend.com/?p=7545</guid>
		<description><![CDATA[<p>This week we tested the public preview of Microsoft SQL Server for Linux using PHP 7 with our component zendframework/zend-db. Microsoft announced the availability of a public preview of SQL Server for Linux on the 16th of November, 2016. This new version of SQL Server has some interesting features such as: transparent data encryption; always encrypted; row level security; in-memory... <a href="https://devzone.zend.com/7545/php-sql-server-linux/">Read more &#187;</a></p>
<p>The post <a rel="nofollow" href="https://devzone.zend.com/7545/php-sql-server-linux/">PHP and SQL Server for Linux</a> appeared first on <a rel="nofollow" href="https://devzone.zend.com">Zend Developer Zone</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>This week we tested the public preview of <a href="https://www.microsoft.com/en-us/sql-server/sql-server-vnext-including-Linux">Microsoft SQL Server for Linux</a> using PHP 7 with our component <a href="https://github.com/zendframework/zend-db">zendframework/zend-db</a>.</p>
<p><a href="https://www.microsoft.com">Microsoft</a> announced the availability of a public preview of SQL Server for Linux on the 16th of November, 2016. This new version of SQL Server has some interesting features such as:</p>
<ul>
<li>transparent data encryption;</li>
<li>always encrypted;</li>
<li>row level security;</li>
<li>in-memory tables;</li>
<li>columnstore indexing;</li>
<li>native JSON support;</li>
<li>support for in-database analytics with R-integration.</li>
</ul>
<p>Moreover, the performance of the new DBMS seems to be very impressive. Microsoft published a case study with <a href="https://blogs.msdn.microsoft.com/sqlcat/2016/10/26/how-bwin-is-using-sql-server-2016-in-memory-oltp-to-achieve-unprecedented-performance-and-scale/">1.2 million requests per second with In-Memory OLTP on a single commodity server</a>.</p>
<p>We tested the last preview of SQL Server (CTP1.2 &#8211; 14.0.200.24) using a <a href="https://www.vagrantup.com/">Vagrant</a> box with Ubuntu 16.04 and 4 GB RAM.</p>
<h2>Install SQL Server on Linux</h2>
<p>We followed the instructions list on the <a href="https://www.microsoft.com/en-us/sql-server/developer-get-started/php-ubuntu">Microsoft website</a> to install SQL Server for PHP on Ubuntu 16.04.</p>
<p>To ensure optimal performance of SQL Server, the Ubuntu box should have at least 4 GB of memory.</p>
<p>The first step is to add the GPG key for the Microsoft repositories.</p>
<pre><code>$ sudo su
$ curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add -
$ curl https://packages.microsoft.com/config/ubuntu/16.04/mssql-server.list &gt; /etc/apt/sources.list.d/mssql-server.list
$ exit</code></pre>
<p>Then we can update the repository list and install the mssql-server package, using the following commands:</p>
<pre><code>$ sudo apt-get update
$ sudo apt-get install mssql-server</code></pre>
<p>Now we can run the setup for sqlserver. We will be required to accept the EULA and choose a password for the <em>System Administrator</em> (SA).</p>
<pre><code>sudo /opt/mssql/bin/sqlservr-setup</code></pre>
<p>After the installation, we will have SQL Server running on Linux!</p>
<h2>Install the command line utility for SQL Server</h2>
<p>Now that we have the DBMS running, we need a tool to access it. Microsoft provides a command line tool named <code>sqlcmd</code>. This program is very similar to the MySQL client tool, quite familiar to PHP developers.</p>
<p>To install <code>sqlcmd</code>, we need to run the following commands:</p>
<pre><code>$ sudo su
$ curl https://packages.microsoft.com/config/ubuntu/16.04/prod.list &gt; /etc/apt/sources.list.d/mssql-tools.list
$ exit
$ sudo apt-get update
$ sudo apt-get install msodbcsql mssql-tools unixodbc-dev
$ echo 'export PATH="$PATH:/opt/mssql-tools/bin"' &gt;&gt; ~/.bash_profile
$ echo 'export PATH="$PATH:/opt/mssql-tools/bin"' &gt;&gt; ~/.bashrc
$ source ~/.bashrc</code></pre>
<blockquote>
<h3>msodbcsql</h3>
<p>Though the Microsoft documentation does not indicate it, we also installed <code>msodbcsql</code>; without it, we ran into dependency issues.</p>
</blockquote>
<p>If the installation was successful, we can start using the command line tool.  For instance, we can ask for the SQL Server vesion using the following instruction:</p>
<pre><code>$ sqlcmd -S localhost -U sa -P yourpassword -Q "SELECT @@VERSION"</code></pre>
<p>where <code>yourpassword</code> should be replaced with the SA password that you choose during the SQL Server setup.</p>
<p>This command will return output like the following:</p>
<pre><code>----------------------------------------------------------------
Microsoft SQL Server vNext (CTP1.2) - 14.0.200.24 (X64)
    Jan 10 2017 19:15:28
    Copyright (C) 2016 Microsoft Corporation. All rights reserved.
    on Linux (Ubuntu 16.04.1 LTS)</code></pre>
<h2>Install the SQL Server extension for PHP</h2>
<p>Next, we need to install the PHP extension for SQL Server. This can be done using <a href="https://pecl.php.net/">PECL</a>.</p>
<blockquote>
<h3>PECL</h3>
<p>If you do not have PECL installed on Ubuntu, you can install it with the following command:</p>
<pre><code>$ sudo apt-get install php-dev</code></pre>
</blockquote>
<p>To install the <code>sqlsrv</code> and <code>pdo_sqlsrv</code> extensions for PHP, we need to execute the following commands:</p>
<pre><code>$ sudo apt-get install unixodbc-dev gcc g++ build-essential
$ sudo pecl install sqlsrv pdo_sqlsrv</code></pre>
<p>Finally, we need to add the directives <code>extension=pdo_sqlsrv.so</code> and <code>extension=sqlsrv.so</code> to our PHP configuration (generally <code>php.ini</code>). In our case, running Ubuntu (or any other Debian-flavored distribution) we have the PHP configuration files stored in <code>/etc/php/7.0/mods-available</code>. We can create <code>sqlsrv.ini</code> and <code>pdo_sqlsrv.ini</code> containing the respective configurations. As a last step, we need to link these configurations to our specific PHP environments.  For this, you can have two choices:</p>
<ul>
<li>For Ubuntu, you can use the <code>phpenmod</code> command.</li>
<li>Alternately, you can symlink to the appropriate directory.</li>
</ul>
<p>For our purposes, we are using PHP 7.0, from the CLI SAPI, so we can do either of the following:</p>
<pre><code># Using phpenmod:
$ sudo phpenmod -v 7.0 -s cli sqlsrv pdo_sqlsrv
# Manually symlinking:
$ sudo ln -s /etc/php/7.0/mods-available/sqlsrv.ini /etc/php/7.0/cli/conf.d/20-sqlsrv.ini
$ sudo ln -s /etc/php/7.0/mods-available/pdo_sqlsrv.ini /etc/php/7.0/cli/conf.d/20-pdo_sqlsrv.ini</code></pre>
<h2>Integration tests with zend-db</h2>
<p>We used the above information to add support for SQL Server to the <a href="https://github.com/zendframework/zend-db">zendframework/zend-db</a> vagrant configuration, used by developers to test against the various database platforms we support.</p>
<p>We updated the <a href="https://github.com/zendframework/zend-db/blob/master/Vagrantfile">Vagrantfile</a>, enabling integration tests for MySQL, PostgreSQL and SQL Server on Linux, to read as follows:</p>
<pre><code>$install_software = &lt;&lt;SCRIPT
export DEBIAN_FRONTEND=noninteractive
apt-get -yq update

# INSTALL PostgreSQL
apt-get -yq install postgresql

# Allow external connections to PostgreSQL as postgres
sed -i "s/#listen_addresses = 'localhost'/listen_addresses = '*'/" /etc/postgresql/9.5/main/postgresql.conf
sed -i "s/peer/trust/" /etc/postgresql/9.5/main/pg_hba.conf
echo 'host all all 0.0.0.0/0 trust' &gt;&gt; /etc/postgresql/9.5/main/pg_hba.conf
service postgresql restart

# INSTALL MySQL
debconf-set-selections &lt;&lt;&lt; "mysql-server mysql-server/root_password password Password123"
debconf-set-selections &lt;&lt;&lt; "mysql-server mysql-server/root_password_again password Password123"
apt-get -yq install mysql-server

# Allow external connections to MySQL as root (with password Password123)
sed -i 's/127\.0\.0\.1/0\.0\.0\.0/g' /etc/mysql/mysql.conf.d/mysqld.cnf
mysql -u root -pPassword123 -e 'USE mysql; UPDATE &lt;code&gt;user&lt;/code&gt; SET &lt;code&gt;Host&lt;/code&gt;="%" WHERE &lt;code&gt;User&lt;/code&gt;="root" AND &lt;code&gt;Host&lt;/code&gt;="localhost"; DELETE FROM &lt;code&gt;user&lt;/code&gt; WHERE &lt;code&gt;Host&lt;/code&gt; != "%" AND &lt;code&gt;User&lt;/code&gt;="root"; FLUSH PRIVILEGES;'
service mysql restart

# INSTALL SQL Server
# More info here: https://www.microsoft.com/en-us/sql-server/developer-get-started/php-ubuntu

curl -s https://packages.microsoft.com/keys/microsoft.asc | apt-key add -
curl -s https://packages.microsoft.com/config/ubuntu/16.04/mssql-server.list &gt; /etc/apt/sources.list.d/mssql-server.list
apt-get -yq update
apt-get -yq install mssql-server
printf "YES\nPassword123\nPassword123\ny\ny" | /opt/mssql/bin/sqlservr-setup

curl -s https://packages.microsoft.com/config/ubuntu/16.04/prod.list &gt; /etc/apt/sources.list.d/mssql-tools.list
apt-get -yq update
ACCEPT_EULA=Y apt-get -yq install msodbcsql mssql-tools unixodbc-dev
echo 'export PATH="$PATH:/opt/mssql-tools/bin"' &gt;&gt; /home/vagrant/.bash_profile
echo 'export PATH="$PATH:/opt/mssql-tools/bin"' &gt;&gt; /home/vagrant/.bashrc
source /home/vagrant/.bashrc
SCRIPT

$setup_vagrant_user_environment = &lt;&lt;SCRIPT
if ! grep "cd /vagrant" /home/vagrant/.profile &gt; /dev/null; then
  echo "cd /vagrant" &gt;&gt; /home/vagrant/.profile
fi
SCRIPT

Vagrant.configure(2) do |config|
  config.vm.box = 'bento/ubuntu-16.04'
  config.vm.provider "virtualbox" do |v|
    v.memory = 4096
    v.cpus = 2
  end

  config.vm.network "private_network", ip: "192.168.20.20"

  config.vm.provision 'shell', inline: $install_software
  config.vm.provision 'shell', privileged: false, inline: '/vagrant/.ci/mysql_fixtures.sh'
  config.vm.provision 'shell', privileged: false, inline: '/vagrant/.ci/pgsql_fixtures.sh'
  config.vm.provision 'shell', privileged: false, inline: '/vagrant/.ci/sqlsrv_fixtures.sh'
  config.vm.provision 'shell', inline: $setup_vagrant_user_environment
end</code></pre>
<p>This vagrant configuration installs Ubuntu 16.04 with 4 GB of RAM and the following databases (<em>user</em> and <em>password</em> are reported in parenthesis):</p>
<ul>
<li>MySQL 5.7.17 (<em>root</em>/<em>Password123</em>)</li>
<li>PostgreSQL 9.5 (<em>postgres</em>/<em>postgres</em>)</li>
<li>SQL Server 14.0.200.24 (<em>sa</em>/<em>Password123</em>)</li>
</ul>
<p>We can use this virtual machine to run <a href="https://phpunit.de/">PHPUnit</a> for the zend-db integration tests.  If you want to test this vagrant box, you can clone the zend-db repository and run the following command:</p>
<pre><code>$ vagrant up</code></pre>
<p>This creates a VM running with IP <code>192.168.20.20</code>.</p>
<h2>More information</h2>
<p>In this post, we&#8217;ve demonstrated how to install the public preview release of SQL Server on Ubuntu.  Microsoft also provides support for other Linux distributions, such as Red Hat and Suse.</p>
<p>You can also install this new SQL Server preview on Windows, macOS, Azure or using a preconfigured Docker container.</p>
<p>Get more information on SQL Server for Linux from the <a href="https://www.microsoft.com/en-us/sql-server/sql-server-vnext-including-Linux">official website</a>.  Find specific information on how to use SQL Server with PHP <a href="https://www.microsoft.com/en-us/sql-server/developer-get-started/php-ubuntu">here</a>.</p>
<blockquote>
<p>This article originally appeared on the Zend Framework blog at <a href="https://framework.zend.com/blog/2017-02-14-php-sql-server-linux.html">https://framework.zend.com/blog/2017-02-14-php-sql-server-linux.html</a> and was written by <a href="http://www.zimuel.it/">Enrico Zimuel</a>.</p>
</blockquote>
<p>The post <a rel="nofollow" href="https://devzone.zend.com/7545/php-sql-server-linux/">PHP and SQL Server for Linux</a> appeared first on <a rel="nofollow" href="https://devzone.zend.com">Zend Developer Zone</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://devzone.zend.com/7545/php-sql-server-linux/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Zend Certified Engineer 2017-PHP</title>
		<link>https://devzone.zend.com/7526/zend-certified-engineer-2017-php/</link>
		<comments>https://devzone.zend.com/7526/zend-certified-engineer-2017-php/#respond</comments>
		<pubDate>Mon, 13 Feb 2017 00:42:18 +0000</pubDate>
		<dc:creator><![CDATA[Cal Evans]]></dc:creator>
				<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">https://devzone.zend.com/?p=7526</guid>
		<description><![CDATA[<p>The new ZCE is here! As of February 13th, 2017, the new Zend Certified Engineer test is available. As with many things in life, it took a lot of effort to get the test updated but we are sure you will find it worth the wait. The new test now tests developers knowledge of PHP and programming concepts through PHP... <a href="https://devzone.zend.com/7526/zend-certified-engineer-2017-php/">Read more &#187;</a></p>
<p>The post <a rel="nofollow" href="https://devzone.zend.com/7526/zend-certified-engineer-2017-php/">Zend Certified Engineer 2017-PHP</a> appeared first on <a rel="nofollow" href="https://devzone.zend.com">Zend Developer Zone</a>.</p>
]]></description>
				<content:encoded><![CDATA[<h2><img src="https://devzone.zend.com/wp-content/uploads/2017/02/zend-cert-eng-2017-php-rgb_lrg-150x150.jpg" alt="The ZCE 2017 logo." width="150" height="150" class="alignright size-thumbnail wp-image-7527" srcset="https://devzone.zend.com/wp-content/uploads/2017/02/zend-cert-eng-2017-php-rgb_lrg-150x150.jpg 150w, https://devzone.zend.com/wp-content/uploads/2017/02/zend-cert-eng-2017-php-rgb_lrg-300x300.jpg 300w, https://devzone.zend.com/wp-content/uploads/2017/02/zend-cert-eng-2017-php-rgb_lrg-768x768.jpg 768w, https://devzone.zend.com/wp-content/uploads/2017/02/zend-cert-eng-2017-php-rgb_lrg-624x624.jpg 624w, https://devzone.zend.com/wp-content/uploads/2017/02/zend-cert-eng-2017-php-rgb_lrg-176x176.jpg 176w, https://devzone.zend.com/wp-content/uploads/2017/02/zend-cert-eng-2017-php-rgb_lrg-60x60.jpg 60w, https://devzone.zend.com/wp-content/uploads/2017/02/zend-cert-eng-2017-php-rgb_lrg-32x32.jpg 32w, https://devzone.zend.com/wp-content/uploads/2017/02/zend-cert-eng-2017-php-rgb_lrg-50x50.jpg 50w, https://devzone.zend.com/wp-content/uploads/2017/02/zend-cert-eng-2017-php-rgb_lrg-64x64.jpg 64w, https://devzone.zend.com/wp-content/uploads/2017/02/zend-cert-eng-2017-php-rgb_lrg-96x96.jpg 96w, https://devzone.zend.com/wp-content/uploads/2017/02/zend-cert-eng-2017-php-rgb_lrg-128x128.jpg 128w, https://devzone.zend.com/wp-content/uploads/2017/02/zend-cert-eng-2017-php-rgb_lrg.jpg 834w" sizes="(max-width: 150px) 100vw, 150px" />The new ZCE is here!</h2>
<p>As of February 13th, 2017, the new Zend Certified Engineer test is available. As with many things in life, it took a lot of effort to get the test updated but we are sure you will find it worth the wait. </p>
<p>The new test now tests developers knowledge of PHP and programming concepts through PHP 7.1.</p>
<p>We would like to thank all the community members that helped up update the test. Without your efforts, this update would not exist. We would like the names of those that helped but we are afraid that they would be inundated with questions about the test. Questions that they aren&#8217;t allowed to answer anyhow. Instead, we will just say thanks. You know who you are.</p>
<p>For more information, and to purchase your voucher, visit the <a href="http://www.zend.com/en/services/certification/php-certification">Zend Certified Engineer</a> web page.</p>
<p><strong>NOTE:</strong> If you have already purchased a voucher to take the ZCE and wish to take the old test, you have until March 31st to schedule and take at. After that point, the old test will no longer be available.</p>
<p>The post <a rel="nofollow" href="https://devzone.zend.com/7526/zend-certified-engineer-2017-php/">Zend Certified Engineer 2017-PHP</a> appeared first on <a rel="nofollow" href="https://devzone.zend.com">Zend Developer Zone</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://devzone.zend.com/7526/zend-certified-engineer-2017-php/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
