<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.0.1">Jekyll</generator><link href="http://localhost:4000/feed.xml" rel="self" type="application/atom+xml" /><link href="http://localhost:4000/" rel="alternate" type="text/html" /><updated>2020-05-20T13:29:21+01:00</updated><id>http://localhost:4000/feed.xml</id><title type="html">Shaun Freeman</title><entry><title type="html">Fixing PHP OPcache mysql_xdevapi Uncaught Error: Call to a member function limit()</title><link href="http://localhost:4000/fixing-php-opcache-mysql-xdevapi-uncaught-error-call-to-a-member-function-limit/" rel="alternate" type="text/html" title="Fixing PHP OPcache mysql_xdevapi Uncaught Error: Call to a member function limit()" /><published>2019-10-07T12:10:48+01:00</published><updated>2019-10-07T12:10:48+01:00</updated><id>http://localhost:4000/fixing-php-opcache-mysql-xdevapi-uncaught-error-call-to-a-member-function-limit</id><content type="html" xml:base="http://localhost:4000/fixing-php-opcache-mysql-xdevapi-uncaught-error-call-to-a-member-function-limit/">&lt;p class=&quot;lead&quot;&gt;I have Been playing with the X DevApi on MySQL 8. It’s really cool idea and I think I will need to write up about it in the near future.
Anyway check it out on PHP Docs, &lt;a href=&quot;https://www.php.net/manual/en/book.mysql-xdevapi.php&quot;&gt;https://www.php.net/manual/en/book.mysql-xdevapi.php&lt;/a&gt; and on the
MySQL site &lt;a href=&quot;https://dev.mysql.com/doc/x-devapi-userguide/en/devapi-users-introduction.html&quot;&gt;https://dev.mysql.com/doc/x-devapi-userguide/en/devapi-users-introduction.html&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This is a very good API which has fluent interfaces for CRUD operations on relational tables and with Document Stores.&lt;/p&gt;

&lt;p&gt;So I come across a bug on &lt;a href=&quot;https://pecl.php.net/package/mysql_xdevapi&quot;&gt;mysql_xdevapi&lt;/a&gt; 8.0.17 this only happens when you have Zend OPcache running at the same time.&lt;/p&gt;

&lt;h2 id=&quot;the-problem&quot;&gt;The Problem&lt;/h2&gt;

&lt;p&gt;So here’s the problem. I am making a collection using the Document Store and then fetching all the records back for pagination, 
so I need to use a &lt;code class=&quot;highlighter-rouge&quot;&gt;limit&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;offset&lt;/code&gt; clause.&lt;/p&gt;

&lt;p&gt;So the code is&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;declare&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;strict_types&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;mysql_xdevapi\getSession&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;nv&quot;&gt;$session&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;getSession&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;mysqlzx://dbuser:!OneTwo3@localhost:33060&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;nv&quot;&gt;$schema&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$session&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getSchema&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'dbname'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$collection&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$schema&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getCollection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'posts'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;nv&quot;&gt;$collection&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;addOrReplaceOne&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'02eb5585a3d74645883b200caa70852f'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'{&quot;author&quot;:&quot;Shaun Freeman&quot;,&quot;title&quot;:&quot;Title 1&quot;,&quot;content&quot;:&quot;Content 1&quot;}'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$collection&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;addOrReplaceOne&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'40089f7d6154426cb28300d05d1ace5c'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'{&quot;author&quot;:&quot;Shaun Freeman&quot;,&quot;title&quot;:&quot;Title 2&quot;,&quot;content&quot;:&quot;Content 2&quot;}'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;So now I’ve made the collection called ‘posts’ with two documents in. Now we need to retrieve all the records so we use&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;nv&quot;&gt;$result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$collection&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'true'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;offset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;limit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;execute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

&lt;span class=&quot;nv&quot;&gt;$result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$result&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;fetchAll&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&amp;lt;pre&amp;gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$result&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$row&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;print_r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$row&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;So now the result we are expecting is&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;Array
&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;_id] &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; 02eb5585a3d74645883b200caa70852f
    &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;title] &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; Title 1
    &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;author] &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; Shaun Freeman
    &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;content] &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; Content 1
&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
Array
&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;_id] &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; 40089f7d6154426cb28300d05d1ace5c
    &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;title] &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; Title 2
    &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;author] &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; Shaun Freeman
    &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;content] &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; Content 2
&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This works fine when Zend OPcache is not loaded but crashes when OPcache is  loaded and enabled it breaks with the error&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;Fatal error: Uncaught Error: Call to a member &lt;span class=&quot;k&quot;&gt;function &lt;/span&gt;limit&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; on bool &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; /home/projects/public/expressive-xdevapi-demo/public/xdevapi.php:21 Stack trace: &lt;span class=&quot;c&quot;&gt;#0 {main} thrown in /home/projects/public/expressive-xdevapi-demo/public/xdevapi.php on line 21&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Now that’s not what I want!&lt;/p&gt;
&lt;h2 id=&quot;the-solution&quot;&gt;The Solution&lt;/h2&gt;

&lt;p&gt;So how to get around this from happening?&lt;/p&gt;

&lt;p&gt;Well I could turn off OPcache but that’s defeating the purpose as I want  my app as fast as possible, it’s OK in development but not in production.&lt;/p&gt;

&lt;p&gt;So while waiting for a fix I found a workaround by treating the collection as a relational table with the &lt;code class=&quot;highlighter-rouge&quot;&gt;mysql_xdevapi\Schema::getCollectionAsTable()&lt;/code&gt;, so we can do the same call but we have to do all the work that &lt;code class=&quot;highlighter-rouge&quot;&gt;find&lt;/code&gt; does for us automatically. So to acheive this we would do&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;nv&quot;&gt;$table&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$schema&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getCollectionAsTable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'posts'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;select&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'*'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;offset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;limit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;execute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

&lt;span class=&quot;nv&quot;&gt;$result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$result&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;fetchAll&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&amp;lt;pre&amp;gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$result&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$row&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;print_r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$row&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This now returns&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;Array
&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;doc] &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;_id&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;02eb5585a3d74645883b200caa70852f&quot;&lt;/span&gt;, &lt;span class=&quot;s2&quot;&gt;&quot;title&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;Title 1&quot;&lt;/span&gt;, &lt;span class=&quot;s2&quot;&gt;&quot;author&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;Shaun Freeman&quot;&lt;/span&gt;, &lt;span class=&quot;s2&quot;&gt;&quot;content&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;Content 1&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;_id] &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; 02eb5585a3d74645883b200caa70852f
&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
Array
&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;doc] &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;_id&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;40089f7d6154426cb28300d05d1ace5c&quot;&lt;/span&gt;, &lt;span class=&quot;s2&quot;&gt;&quot;title&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;Title 2&quot;&lt;/span&gt;, &lt;span class=&quot;s2&quot;&gt;&quot;author&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;Shaun Freeman&quot;&lt;/span&gt;, &lt;span class=&quot;s2&quot;&gt;&quot;content&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;Content 2&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;_id] &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; 40089f7d6154426cb28300d05d1ace5c
&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Not quite there yet as I want an associative array like the one earlier. As the &lt;code class=&quot;highlighter-rouge&quot;&gt;getCollectionAsTable()&lt;/code&gt; function returns an array of rows with an ‘_id’ key and an ‘doc’ key. it’s the ‘doc’ key we only want so we can alter the &lt;code class=&quot;highlighter-rouge&quot;&gt;foreach()&lt;/code&gt; loop to&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;k&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$result&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$row&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;array_key_exists&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'doc'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$row&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$row&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$row&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'doc'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;print_r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$row&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Which gives us&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-json&quot; data-lang=&quot;json&quot;&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;_id&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;02eb5585a3d74645883b200caa70852f&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;title&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Title 1&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;author&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Shaun Freeman&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;content&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Content 1&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;So we just get the raw JSON string so I need now to decode the JSON with &lt;code class=&quot;highlighter-rouge&quot;&gt;json_decode()&lt;/code&gt; function, so now to rewrite the &lt;code class=&quot;highlighter-rouge&quot;&gt;foreach()&lt;/code&gt; loop which look like&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;k&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$result&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$row&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;array_key_exists&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'doc'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$row&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$row&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;json_decode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$row&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'doc'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;print_r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$row&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;And this gives us the output of&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;Array
&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;_id] &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; 02eb5585a3d74645883b200caa70852f
    &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;title] &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; Title 1
    &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;author] &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; Shaun Freeman
    &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;content] &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; Content 1
&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
Array
&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;_id] &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; 40089f7d6154426cb28300d05d1ace5c
    &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;title] &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; Title 2
    &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;author] &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; Shaun Freeman
    &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;content] &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; Content 2
&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This is what I want. So I’ve now got the desired output from the collection while keeping OPcache on. Time pat myself on the back and enjoy a nice cup of coffee!&lt;/p&gt;

&lt;p&gt;Here’s the full script with the work around&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;declare&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;strict_types&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;mysql_xdevapi\getSession&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;nv&quot;&gt;$session&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;getSession&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;mysqlzx://dbuser:!OneTwo3@localhost:33060&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;nv&quot;&gt;$schema&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$session&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getSchema&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'dbname'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$collection&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$schema&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getCollection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;posts&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;nv&quot;&gt;$collection&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;addOrReplaceOne&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'02eb5585a3d74645883b200caa70852f'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'{&quot;author&quot;:&quot;Shaun Freeman&quot;,&quot;title&quot;:&quot;Title 1&quot;,&quot;content&quot;:&quot;Content 1&quot;}'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$collection&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;addOrReplaceOne&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'40089f7d6154426cb28300d05d1ace5c'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'{&quot;author&quot;:&quot;Shaun Freeman&quot;,&quot;title&quot;:&quot;Title 2&quot;,&quot;content&quot;:&quot;Content 2&quot;}'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nv&quot;&gt;$result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$collection&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'true'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;offset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;limit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;execute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Throwable&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$throwable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// Fatal error: Uncaught Error: Call to a member function limit() on bool&lt;/span&gt;
    &lt;span class=&quot;nv&quot;&gt;$table&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$schema&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getCollectionAsTable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'posts'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;nv&quot;&gt;$result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$table&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;select&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'*'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;offset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;limit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;execute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nv&quot;&gt;$result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$result&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;fetchAll&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&amp;lt;pre&amp;gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$result&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$row&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;array_key_exists&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'doc'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$row&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$row&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;json_decode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$row&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'doc'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;//$row = $row['doc'];&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;print_r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$row&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;I hope this was useful to you. I hope this gets fixed soon too.&lt;/p&gt;

&lt;p&gt;This extension is still young and is a real game changer as I don’t have to write SQL for simple a CRUD and I don’t have to use a library like Doctrine or Zend\DB, keeping the code base and libraries to a minimum is always good!&lt;/p&gt;

&lt;p&gt;What do you think, let me know and happy coding!&lt;/p&gt;</content><author><name>Shaun Freeman</name></author><category term="PHP Linux" /><category term="MySQL" /><category term="PHP" /><summary type="html">I have Been playing with the X DevApi on MySQL 8. It’s really cool idea and I think I will need to write up about it in the near future. Anyway check it out on PHP Docs, https://www.php.net/manual/en/book.mysql-xdevapi.php and on the MySQL site https://dev.mysql.com/doc/x-devapi-userguide/en/devapi-users-introduction.html.</summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://localhost:4000/assets/img/php-logo.png" /><media:content medium="image" url="http://localhost:4000/assets/img/php-logo.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Setting Up A Testing Environment For PHP Using VirtualBox - Part 4 Installing MySQL</title><link href="http://localhost:4000/setting-up-a-testing-environment-for-php-using-virtualbox-part-4-installing-mysql/" rel="alternate" type="text/html" title="Setting Up A Testing Environment For PHP Using VirtualBox - Part 4 Installing MySQL" /><published>2018-09-13T11:09:24+01:00</published><updated>2018-09-13T11:09:24+01:00</updated><id>http://localhost:4000/setting-up-a-testing-environment-for-php-using-virtualbox-part-4-installing-mysql</id><content type="html" xml:base="http://localhost:4000/setting-up-a-testing-environment-for-php-using-virtualbox-part-4-installing-mysql/">&lt;p class=&quot;lead&quot;&gt;Now we have installed Nginx the next part before we compile and install PHP is to install and configure MySQL. So let’s get to it.&lt;/p&gt;

&lt;p&gt;This is a very trivial operation so should be quick. First we install MySQL from the repository with&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;apt &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;mysql-server mysql-client&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;During the installation you will be asked to set a root MySQL password, just remember what you set!&lt;/p&gt;

&lt;p&gt;Next a good practice is to run ‘mysql_secure_installation’ command so&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;mysql_secure_installation&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;We will then be asked a series of questions which we will answer ‘yes’ or ‘no’&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;First we will be asked for our root password, enter it now.&lt;/li&gt;
  &lt;li&gt;Validate Password plugin: No&lt;/li&gt;
  &lt;li&gt;Change the root password: No&lt;/li&gt;
  &lt;li&gt;Remover Anonymous users : Yes&lt;/li&gt;
  &lt;li&gt;Disallow root login remotely: Yes&lt;/li&gt;
  &lt;li&gt;Remove test databases: Yes&lt;/li&gt;
  &lt;li&gt;Reload Privileges: Yes&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We we have done that we can test our connection by&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;mysql &lt;span class=&quot;nt&quot;&gt;-uroot&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-p&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Enter your password when propted and the you should see someting like&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;Welcome to the MySQL monitor.  Commands end with &lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; or &lt;span class=&quot;se&quot;&gt;\g&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;.&lt;/span&gt;
Your MySQL connection &lt;span class=&quot;nb&quot;&gt;id &lt;/span&gt;is 3
Server version: 5.7.23-0ubuntu0.16.04.1 &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;Ubuntu&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;

Copyright &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;c&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; 2000, 2018, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type &lt;span class=&quot;s1&quot;&gt;'help;'&lt;/span&gt; or &lt;span class=&quot;s1&quot;&gt;'\h'&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;help. Type &lt;span class=&quot;s1&quot;&gt;'\c'&lt;/span&gt; to clear the current input statement.

mysql&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Here we can see the mysql propt and can now query ant databases. To quit this just type quit then press enter.&lt;/p&gt;

&lt;p&gt;And that it for this one. Next one will compile and install PHP.&lt;/p&gt;

&lt;p&gt;In the meantime happy code guys!&lt;/p&gt;

&lt;p&gt;Watch on youtube: &lt;a href=&quot;https://youtu.be/EXpI-RKVKI4&quot;&gt;Setting Up A Test Environment For PHP In VirtualBox - Part 4 Installing MySQL&lt;/a&gt;&lt;/p&gt;</content><author><name>Shaun Freeman</name></author><category term="Virtual Box" /><category term="Linux" /><category term="MySQL" /><summary type="html">Now we have installed Nginx the next part before we compile and install PHP is to install and configure MySQL. So let’s get to it.</summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://localhost:4000/assets/img/virtualbox/PHP-tutorial-Part4.png" /><media:content medium="image" url="http://localhost:4000/assets/img/virtualbox/PHP-tutorial-Part4.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Setting Up A Testing Environment For PHP Using VirtualBox - Part 3 Installing Nginx</title><link href="http://localhost:4000/setting-up-a-testing-environment-for-php-using-virtualbox-part-3-installing-nginx/" rel="alternate" type="text/html" title="Setting Up A Testing Environment For PHP Using VirtualBox - Part 3 Installing Nginx" /><published>2018-09-12T18:09:39+01:00</published><updated>2018-09-12T18:09:39+01:00</updated><id>http://localhost:4000/setting-up-a-testing-environment-for-php-using-virtualbox-part-3-installing-nginx</id><content type="html" xml:base="http://localhost:4000/setting-up-a-testing-environment-for-php-using-virtualbox-part-3-installing-nginx/">&lt;p class=&quot;lead&quot;&gt;Now we have got our server install it’s time to install Nginx. This is pretty straight forward and I have covered it before but for this series I thought I would make sure I cover this simply.&lt;/p&gt;

&lt;p&gt;First to makes things simple we will make sure we can access the server using an canonical URL instead of an IP address so fire up the server we created in part 2, log in with the username and password you set.&lt;/p&gt;

&lt;p&gt;We will install Avahi to do this so on the command line write&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;apt &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;avahi-daemon&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;press &lt;code class=&quot;highlighter-rouge&quot;&gt;enter&lt;/code&gt;. Once avahi is installed make sure the hostname and hosts file are correct so on the command line again&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;nano /etc/hostname&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;and make sure it reads&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;php-projects&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;press &lt;code class=&quot;highlighter-rouge&quot;&gt;Ctrl o&lt;/code&gt; then &lt;code class=&quot;highlighter-rouge&quot;&gt;Ctrl x&lt;/code&gt; to save and close nano. Again for hosts file&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;nano /etc/hosts&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;and make sure the second line reads&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;127.0.1.1       php-projects.local      php-projects&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;press &lt;code class=&quot;highlighter-rouge&quot;&gt;Ctrl o&lt;/code&gt; then &lt;code class=&quot;highlighter-rouge&quot;&gt;Ctrl x&lt;/code&gt; to save and close nano and reboot the server with&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;reboot&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Now we should be able to navigate to our server using the URL of ‘http://php-projects’, but we will do that when Nginx is installed.&lt;/p&gt;

&lt;p&gt;We need now log in to our server to install Nginx. This is a trivial as getting it from the Ubuntu repos, so on the command line write&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;apt &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;nginx&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;press &lt;code class=&quot;highlighter-rouge&quot;&gt;enter&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;That should install Nginx for us. We can check Nginx is working by putting the URL ‘http://php-projects.local’ in our browser and you should see the default Nginx site like&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/virtualbox/Screenshot from 2018-09-12 15-10-05.png&quot; alt=&quot;Nginx default page&quot; class=&quot;img-fluid&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Now  done we need to configure it to serve our files. We will ask it to serve from a folder called ‘public’ our user folder. To do this we will need to create a ‘public’ folder in our home directory (‘/home/tutorial’) and to create a config file in ‘/etc/nginx/sites-enabled’ folder. First we will need to remove the default site config so on the command line&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nb&quot;&gt;rm&lt;/span&gt; /etc/nginx/sites-enabled/default&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;now lets make our site config file with&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;nano /etc/nginx/sites-enabled/php-projects&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;and in that file put&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-nano&quot; data-lang=&quot;nano&quot;&gt;server {
    root /home/tutorial/public;
    server_name php-projects.local;
    index index.html;

    location / {
        try_files $uri $uri/ = 404
    }
}&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;here we are defining at&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;line 2: a root directory located at ‘/home/tutorial/public’&lt;/li&gt;
  &lt;li&gt;line 3: the name of the website ‘php-projects.local’&lt;/li&gt;
  &lt;li&gt;line 4: the file to serve automatically&lt;/li&gt;
  &lt;li&gt;line 5: a location block to add some rules about serving pages&lt;/li&gt;
  &lt;li&gt;line6: we ask Nginx to try the URI if there serve it else give us a 404 ‘Page Not Found’.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All this has to be within a server block.&lt;/p&gt;

&lt;p&gt;Save this file with &lt;code class=&quot;highlighter-rouge&quot;&gt;Ctrl o&lt;/code&gt; then &lt;code class=&quot;highlighter-rouge&quot;&gt;Ctrl x&lt;/code&gt; and restart nginx with&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;systemctl restart nginx&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;We will now make our public directory so enter&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nb&quot;&gt;mkdir &lt;/span&gt;public&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Then we will make a ‘index.html’ file and add a bit of html so to do this we use&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;nano public/index.html&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;then in this file put&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-nano&quot; data-lang=&quot;nano&quot;&gt;&amp;lt;h1&amp;gt;Welcome to my website&amp;lt;/h1&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Save this file with &lt;code class=&quot;highlighter-rouge&quot;&gt;Ctrl o&lt;/code&gt; then &lt;code class=&quot;highlighter-rouge&quot;&gt;Ctrl x&lt;/code&gt;. So now to test this out we can refresh our browser (‘http://php-projects.local’) and you should see something like below&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/virtualbox/Screenshot from 2018-09-12 18-16-46.png&quot; alt=&quot;Wesite index page&quot; class=&quot;img-fluid&quot; /&gt;&lt;/p&gt;

&lt;p&gt;And that’s it for this one. In the next part we shall install MySQL rerady for the installation of PHP.&lt;/p&gt;

&lt;p&gt;Thanks and there is a video to see me set this up below. Happy coding people! And as usual you can leave a comment too.&lt;/p&gt;

&lt;p&gt;Watch on youtube: &lt;a href=&quot;https://www.youtube.com/watch?v=pD4f6XFK2Aw&amp;amp;t=19s&quot;&gt;Setting Up A Test Environment For PHP In VirtualBox - Part 3 Installing Nginx&lt;/a&gt;&lt;/p&gt;</content><author><name>Shaun Freeman</name></author><category term="Virtual Box" /><category term="Linux" /><category term="Nginx" /><summary type="html">Now we have got our server install it’s time to install Nginx. This is pretty straight forward and I have covered it before but for this series I thought I would make sure I cover this simply.</summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://localhost:4000/assets/img/virtualbox/PHP-tutorial-Part3.png" /><media:content medium="image" url="http://localhost:4000/assets/img/virtualbox/PHP-tutorial-Part3.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Filtering HTML in Zend Framework Using HTML Purifier</title><link href="http://localhost:4000/filtering-html-in-zend-framework-using-html-purifier/" rel="alternate" type="text/html" title="Filtering HTML in Zend Framework Using HTML Purifier" /><published>2017-09-27T11:09:31+01:00</published><updated>2017-09-27T11:09:31+01:00</updated><id>http://localhost:4000/filtering-html-in-zend-framework-using-html-purifier</id><content type="html" xml:base="http://localhost:4000/filtering-html-in-zend-framework-using-html-purifier/">&lt;p class=&quot;lead&quot;&gt;If you have forms where you allow users to submit HTML content you will want to filter that so you can be sure that no malicious code gets through, some WYSIWYG editors do this but not all but still as we are paranoid backend developers we don’t trust any input submitted by users.&lt;/p&gt;

&lt;p&gt;Filtering data is rather trivial in &lt;a href=&quot;https://framework.zend.com/&quot;&gt;Zend Framework&lt;/a&gt; as we have a built in filter called ‘StripTags’ but with HTML we want those tags! We could use BBCode or Markdown but these are not as user friendly as a WYSIWYG editor like &lt;a href=&quot;https://summernote.org/&quot;&gt;Summernote&lt;/a&gt;, &lt;a href=&quot;https://www.tinymce.com/&quot;&gt;TinyMCE&lt;/a&gt; or &lt;a href=&quot;https://ckeditor.com/&quot;&gt;CKEditor&lt;/a&gt;. So what can we do? This is where &lt;a href=&quot;http://htmlpurifier.org/&quot;&gt;HTML Purifier&lt;/a&gt; comes to our aid and it’s quite easy to integrate into &lt;a href=&quot;https://framework.zend.com/&quot;&gt;Zend Framework&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In the follow code examples I am using PHP 7 syntax as there are great new features in PHP 7, also I am in the process of upgrading my Zend Framework 2 code to Zend Framework 3 so the examples will be  Zend Framwork 3 ready but work also in Zend Framework 2, (upgrading all my code is going to take some time).&lt;/p&gt;

&lt;p&gt;First we have to include the HTML Purifier code library and as we are using &lt;a href=&quot;https://getcomposer.org/&quot;&gt;Composer&lt;/a&gt; this is easy. (if you are not using Composer then you will have to add the library manually.)&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# If composer is installed globally use&lt;/span&gt;
composer require ezyang/htmlpurifier

&lt;span class=&quot;c&quot;&gt;# If you have composer in your project directory then&lt;/span&gt;
php composer.phar require ezyang/htmlpurifier&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Once that’s done we can write our filter which we will extend ‘Zend\Filter\AbstractFilter’. The basics of HTML Purifier is mind numbingly simple, to filter your code the basic principle is&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class=&quot;nv&quot;&gt;$dirtyHtml&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$_POST&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'html'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$config&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;array&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;of&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;config&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$htmlPurifier&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;\HTMLPurifier&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$htmlPurifier&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;purify&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$dirtyHtml&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;So with this knowledge let’s integrate this filter into Zend Framwork so first let’s make our filter class which I will put in my module folder in this case ‘/module/Application/src/Application/Filter’, notice I am still using the Zend Framework 2 module layout. So our Filter class will look like&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;declare&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;strict_types&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Application\Filter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;HTMLPurifier&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Zend\Filter\AbstractFilter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;HtmlPurifierFilter&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;AbstractFilter&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;cd&quot;&gt;/**
     * @var HTMLPurifier
     *
     */&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$instance&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__construct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;HTMLPurifier&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$htmlPurifier&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$htmlPurifier&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;instance&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;purify&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This is a Straight forward filter where the constructor expects an HTMLPurifier class instance and the filter method expects to return a purified string. To be able to use this filter plugin in a Zend\Form we have to tell the FilterPluginManager about it but as we said the constructor expects the HTMLPurifier instance so to get that into the constructor we will need to write a Factory class which we will create in  ‘/module/Application/src/Application/Filter/Service’ called ‘HtmlPurifierFactory’ and would look like&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;declare&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;strict_types&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Application\Filter\Service&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Application\Filter\HtmlPurifierFilter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;HTMLPurifier&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Interop\Container\ContainerInterface&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Traversable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Zend\Filter\FilterPluginManager&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Zend\ServiceManager\Exception\InvalidServiceException&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Zend\ServiceManager\FactoryInterface&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Zend\ServiceManager\ServiceLocatorInterface&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;HtmlPurifierFactory&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;FactoryInterface&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;cd&quot;&gt;/**
     * Options to pass to the constructor (when used in v2), if any.
     *
     * @param null|array
     */&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$creationOptions&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[];&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__construct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$creationOptions&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$creationOptions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$creationOptions&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;instanceof&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Traversable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;nv&quot;&gt;$creationOptions&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;iterator_to_array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$creationOptions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;is_array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$creationOptions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;InvalidServiceException&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;sprintf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                &lt;span class=&quot;s1&quot;&gt;'%s cannot use non-array, non-traversable creation options; received %s'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;__CLASS__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;is_object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$creationOptions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;get_class&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$creationOptions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;gettype&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$creationOptions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;creationOptions&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$creationOptions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__invoke&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ContainerInterface&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$container&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$requestedName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;array&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$options&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;HtmlPurifierFilter&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;cd&quot;&gt;/** @var FilterPluginManager $container */&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$config&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$container&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getServiceLocator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'config'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;nv&quot;&gt;$config&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'html_purifier'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[];&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$options&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;nv&quot;&gt;$config&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;array_merge&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$options&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;nv&quot;&gt;$htmlPurifier&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;HTMLPurifier&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;HtmlPurifierFilter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$htmlPurifier&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;createService&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ServiceLocatorInterface&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$serviceLocator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;HtmlPurifierFilter&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$serviceLocator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;creationOptions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;setCreationOptions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;array&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$options&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;creationOptions&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$options&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This code is ZF3 compatible we have have  ‘createService’ and ‘setCreationOptions’ which are needed for ZF2 which just then calls the ‘__invoke’ method which is for ZF3, correct me if I’m wrong! Still getting my head around all the new changes in ZF3. In the ‘__invoke’ method we call the ‘ServiceLocator’ to get the application config array and specifically ask for the key ‘html_purifier’ this is where our HTML Purifier options will live also we merge this with the options passed in so that in our form we can override or add new options specific to what we want.&lt;/p&gt;

&lt;p&gt;Next we have to tell the plugin helper about our new filter so in ‘/module/Application/config/module.config.php’ we will add a new key like&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;

    &lt;span class=&quot;s1&quot;&gt;'filters'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;'factories'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
            &lt;span class=&quot;nx&quot;&gt;\Application\Filter\HtmlPurifierFilter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;\Application\Filter\Service\HtmlPurifierFactory&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Now make a config file in our ‘/config/autoload’ folder called ‘htmlpurifier.local.php’ for our options, for this we will just have one option which is the cache directory so&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;s1&quot;&gt;'html_purifier'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;'Cache.SerializerPath'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;__DIR__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'/../../data/cache'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Now it’s time to make our form. So make a new file in ‘/module/Application/src/Application/Form’ called ‘BlogPost.php’ like (this is for demo only just modify your forms according).&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt; 

&lt;span class=&quot;k&quot;&gt;declare&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;strict_types&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Application\Form&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Application\Filter\HtmlPurifierFilter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Zend\Filter\StringTrim&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Zend\Filter\StripTags&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Zend\Form\Element\Textarea&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Zend\Form\Form&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Zend\InputFilter\InputFilterProviderInterface&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Zend\Validator\StringLength&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;BlogPost&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Form&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;InputFilterProviderInterface&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;
            &lt;span class=&quot;s1&quot;&gt;'type'&lt;/span&gt;  &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Textarea&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;s1&quot;&gt;'name'&lt;/span&gt;  &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'html'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;s1&quot;&gt;'options'&lt;/span&gt;   &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
                &lt;span class=&quot;s1&quot;&gt;'label'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'HTML'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
            &lt;span class=&quot;s1&quot;&gt;'attributes'&lt;/span&gt;    &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
                &lt;span class=&quot;s1&quot;&gt;'rows'&lt;/span&gt;  &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;getInputFilterSpecification&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;array&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
            &lt;span class=&quot;s1&quot;&gt;'html'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
                &lt;span class=&quot;s1&quot;&gt;'required'&lt;/span&gt;  &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;s1&quot;&gt;'filters'&lt;/span&gt;   &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
                    &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'name'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;StringTrim&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
                    &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'name'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;HtmlPurifierFilter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'options'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
                        &lt;span class=&quot;c1&quot;&gt;// any overriding options here&lt;/span&gt;
                    &lt;span class=&quot;p&quot;&gt;]],&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
                &lt;span class=&quot;s1&quot;&gt;'validators'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
                    &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'name'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;StringLength&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'options'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
                        &lt;span class=&quot;s1&quot;&gt;'encoding'&lt;/span&gt;  &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'UTF-8'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                        &lt;span class=&quot;s1&quot;&gt;'max'&lt;/span&gt;       &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;65535&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                    &lt;span class=&quot;p&quot;&gt;]],&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Here you can see we have added our filters for the form element ‘html’ and our new Filter ‘HtmlPurifierFilter’, here you can add any other options to pass on to HTMLPurifier. Now tell the Service Manager where to find our form so back in ‘/module/Application/config/module.config.php’ add&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
    &lt;span class=&quot;s1&quot;&gt;'form_elements'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;'invokables'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
            &lt;span class=&quot;nx&quot;&gt;Application\Form\BlogPost&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;  &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Application\Form\BlogPost&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Now when you call your form from the ‘FormElementManager’ it will automatically add our filters and validators and in this case filter any html and remove any JavaScript and clean up the html.&lt;/p&gt;

&lt;p&gt;So it’s over to you now, any improvements or things I got wrong or general chat let me know in the comments below and as always&lt;/p&gt;

&lt;p&gt;Happy Coding!&lt;/p&gt;</content><author><name>Shaun Freeman</name></author><category term="PHP" /><category term="Zend Framework" /><summary type="html">If you have forms where you allow users to submit HTML content you will want to filter that so you can be sure that no malicious code gets through, some WYSIWYG editors do this but not all but still as we are paranoid backend developers we don’t trust any input submitted by users.</summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://localhost:4000/assets/img/zf1.png" /><media:content medium="image" url="http://localhost:4000/assets/img/zf1.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Nginx: Using Regex to Configure Dynamic Location Blocks</title><link href="http://localhost:4000/nginx-using-regex-to-configure-dynamic-location-blocks/" rel="alternate" type="text/html" title="Nginx: Using Regex to Configure Dynamic Location Blocks" /><published>2017-09-24T13:09:39+01:00</published><updated>2017-09-24T13:09:39+01:00</updated><id>http://localhost:4000/nginx-using-regex-to-configure-dynamic-location-blocks</id><content type="html" xml:base="http://localhost:4000/nginx-using-regex-to-configure-dynamic-location-blocks/">&lt;p class=&quot;lead&quot;&gt;I love Nginx as a webserver, it’s quick and easy to configure (if you know what you are doing). As a web developer (or should I say programmer), I like to make things as easy as possible in my development environment. As my projects have increased over time I have noticed my Nginx config growing to accommodate each project.&lt;/p&gt;

&lt;p&gt;My project directory looks something like:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;root
├──project-1
│  └──public
|     └──index.php
├──project-2
|  └──public_html
|     └──index.php
└──project-3
   └──public
      └──index.php&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;And this goes on for a lots more projects using the same directory structure.&lt;/p&gt;

&lt;p&gt;Now my Nginx conf file for this looks like, as all my projects use MVC all requests are routed through &lt;code class=&quot;highlighter-rouge&quot;&gt;index.php&lt;/code&gt;&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-nano&quot; data-lang=&quot;nano&quot;&gt;server {
    listen 80;

    root /home/shaun/root;
    index index.html index.php;

    # Make site accessible from http://localhost/
    server_name localhost;
    client_max_body_size 100M;

    location / {
        try_files $uri $uri/ /index.php$is_args$args;
        autoindex on;
    }

    location /site-1/public {
        try_files $uri $uri/ /site-1/public/index.php?$is_args$args;
    }

    location /site-2/public_html {
        try_files $uri $uri/ /site-2/public_html/index.php?$is_args$args;
    }

    location /site-3/public {
        try_files $uri $uri/ /site-3/public/index.php?$is_args$args;
    }

    location  ~ \.(php)$ {
        proxy_buffer_size 128k;
        proxy_buffers 4 128k;

        fastcgi_keep_conn on;
        fastcgi_buffers 16 128k;
        fastcgi_buffer_size 128k;

        fastcgi_pass   unix:/usr/local/php7.1/var/run/php-fpm.sock;
        fastcgi_read_timeout 1200;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include        fastcgi_params;
    }
}&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;As you can see each site under root gets its own location block as if I didn’t do this this then then a url like &lt;code class=&quot;highlighter-rouge&quot;&gt;http://localhost/site-1/public/blog/list&lt;/code&gt; would result in a rude default Nginx 404 &lt;strong&gt;file not found&lt;/strong&gt; page instead of my sites blog list! You can see problems with this approach&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Each new site I have to add a new location block and restart the server&lt;/li&gt;
  &lt;li&gt;Each time I delete a project I have to delete the location block and restart the server&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Well I didn’t want to keep adding/deleting sites from the config file. So what could I do? Looking over the location blocks and directory structure I saw a pattern and wondered if I could abstract all sites into one location block. This is what I came up with using regex for the location parameter.&lt;/p&gt;

&lt;p&gt;First I put my php-fpm config in an include file in /etc/nginx&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-nano&quot; data-lang=&quot;nano&quot;&gt;proxy_buffer_size 128k;
proxy_buffers 4 128k;

fastcgi_keep_conn on;
fastcgi_buffers 16 128k;
fastcgi_buffer_size 128k;

fastcgi_read_timeout 1200;
fastcgi_index  index.php;
fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
include        fastcgi_params;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Then I rewrote my site config file in ‘/etc/nginx/sites-enabled/projects.conf’&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-nano&quot; data-lang=&quot;nano&quot;&gt;server {
    listen 80;

    root /home/shaun/Web-Projects;
    index index.html index.php;

    # Make site accessible from http://localhost/
    server_name localhost;
    client_max_body_size 100M;

    location / {
        try_files $uri $uri/ /index.html;
        autoindex on;
    }

    location ~ /(.*)/(public_html|public) {

        try_files $uri $uri/ /$1/$2/index.php$is_args$args;

        location ~ \.(php)$ {
            include        php-fpm.conf;
            fastcgi_pass   unix:/usr/local/php7.1/var/run/php-fpm.sock;
        }
    }

    location ~ \.(php)$ {
        include        php-fpm.conf;
        fastcgi_pass   unix:/usr/local/php7.1/var/run/php-fpm.sock;
    }
}&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Restart the server and now all my projects work that use this directory structure. Breaking down the new location block at lines 16-25&lt;/p&gt;

&lt;p&gt;line 16 is the regex pattern &lt;code class=&quot;highlighter-rouge&quot;&gt;~ /(.*)/(public_html|public)&lt;/code&gt; This pattern has two groups, the first group matches any character after ‘/’ which will match &lt;code class=&quot;highlighter-rouge&quot;&gt;/site-1&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;/site-2/sub-site&lt;/code&gt; etc. The next group matches the directory &lt;code class=&quot;highlighter-rouge&quot;&gt;public&lt;/code&gt; or &lt;code class=&quot;highlighter-rouge&quot;&gt;public_html&lt;/code&gt; after the next &lt;code class=&quot;highlighter-rouge&quot;&gt;/&lt;/code&gt; so will match &lt;code class=&quot;highlighter-rouge&quot;&gt;/site-1/public&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;/site-2/public_html&lt;/code&gt; etc.&lt;/p&gt;

&lt;p&gt;line 18 is the try_file directive which will check if the file or directory exists id so will server them if none of these is found it will server the ‘index.php’ defined by the regex groups as an example: &lt;code class=&quot;highlighter-rouge&quot;&gt;/&amp;lt;first group&amp;gt;/&amp;lt;second group&amp;gt;/index.php&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I can now add and delete project site without touching the nginx config or restarting the server! :-)&lt;/p&gt;

&lt;h2 id=&quot;multiple-php-config&quot;&gt;Multiple PHP Config&lt;/h2&gt;

&lt;p&gt;Wait on a minute, after this I started wondering if I could run different PHP versions just by altering the URL to a prefix like &lt;code class=&quot;highlighter-rouge&quot;&gt;/php/7.0&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;/php/7/1&lt;/code&gt; or &lt;code class=&quot;highlighter-rouge&quot;&gt;/php/7.2&lt;/code&gt;. So with my new found knowledge of regex I set too.&lt;/p&gt;

&lt;p&gt;Now my PHP versions are in separate directories:&lt;/p&gt;

&lt;p&gt;/usr/local/php7.0&lt;br /&gt;
/usr/local/php7.1&lt;br /&gt;
/usr/local/php7.2&lt;/p&gt;

&lt;p&gt;Yet another pattern we can use with regex so I come up with additional location block look like&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-nano&quot; data-lang=&quot;nano&quot;&gt;....

location ~ ^/php/(7.0|7.1|7.2)(/.*/(public_html|public))? {

    try_files $uri $uri/ /php/$1$2/index.php$is_args$args;

    location ~ /php/(7.0|7.1|7.2).*\.(php)$ {
        include        php-fpm.conf;
        fastcgi_pass   unix:/usr/local/php$1/var/run/php-fpm.sock;
    }
}

....&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Here I am using a new pattern to check if the URI starts with &lt;code class=&quot;highlighter-rouge&quot;&gt;/php/&lt;/code&gt; then check the first group &lt;code class=&quot;highlighter-rouge&quot;&gt;(7.0|7.1|7.2)&lt;/code&gt; this group matches which version I want then second and third group is the same as above but is optional and in the &lt;code class=&quot;highlighter-rouge&quot;&gt;try_files&lt;/code&gt; directive I alter the directory structure to the matched pattern.&lt;/p&gt;

&lt;p&gt;In the sub location block I again use regex to capture the PHP version number I want to run and use the matched pattern to the &lt;code class=&quot;highlighter-rouge&quot;&gt;fastcgi_pass&lt;/code&gt; directive.&lt;/p&gt;

&lt;p&gt;Lastly I create the directories for this to work&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nb&quot;&gt;mkdir&lt;/span&gt; /home/shaun/Web-Projects/php
&lt;span class=&quot;nb&quot;&gt;ln&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-s&lt;/span&gt; /home/shaun/Web-Projects home/shaun/Web-Projects/php/7.0
&lt;span class=&quot;nb&quot;&gt;ln&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-s&lt;/span&gt; /home/shaun/Web-Projects home/shaun/Web-Projects/php/7.1
&lt;span class=&quot;nb&quot;&gt;ln&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-s&lt;/span&gt; /home/shaun/Web-Projects home/shaun/Web-Projects/php/7.2&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;I restarted the server and tested my new block and YES! it worked now when I use the PHP prefixes in my URI I run that PHP version as you can see from the screen capture blow&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/php-7.0.png&quot; alt=&quot;php7.o.png&quot; class=&quot;img-fluid&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/php7.1.png&quot; alt=&quot;php7.1.png&quot; class=&quot;img-fluid&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/php7.2.png&quot; alt=&quot;php7.2.png&quot; class=&quot;img-fluid&quot; /&gt;&lt;/p&gt;

&lt;p&gt;So Now my Nginx confix file looks like&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-nano&quot; data-lang=&quot;nano&quot;&gt;server {
    listen 80;

    root /home/shaun/Web-Projects;
    index index.html index.php;

    # Make site accessible from http://localhost/
    server_name localhost;
    client_max_body_size 100M;

    location / {
        try_files $uri $uri/ index.php$is_args$args;
        autoindex on;
    }

    location ~ ^/php/(7.0|7.1|7.2)(/.*/(public_html|public))? {

        try_files $uri $uri/ /php/$1$2/index.php$is_args$args;
        autoindex on;

        location ~ /php/(7.0|7.1|7.2).*\.(php)$ {
            include        php-fpm.conf;
            fastcgi_pass   unix:/usr/local/php$1/var/run/php-fpm.sock;
        }
    }

    location ~ /(.*)/(public_html|public) {

        try_files $uri $uri/ /$1/$2/index.php$is_args$args;

        location ~ \.(php)$ {
            include        php-fpm.conf;
            fastcgi_pass   unix:/usr/local/php7.1/var/run/php-fpm.sock;
        }
    }

    location ~ \.(php)$ {
        include        php-fpm.conf;
        fastcgi_pass   unix:/usr/local/php7.1/var/run/php-fpm.sock;
    }
}&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;A lot shorter and zero maintenance plus the ability to see all my sites in different PHP versions all at once just by changing the URL :-) Super!&lt;/p&gt;

&lt;p&gt;Hope this helps and I would love to hear your comments on this and any improvements or different applications of this I would love to hear too.&lt;/p&gt;

&lt;p&gt;See ya soon and happy coding!&lt;/p&gt;

&lt;p&gt;Watch on youtube: Setting Up A Test Environment For PHP In VirtualBox - Part 6 Installing Multiple PHP Versions&lt;/p&gt;</content><author><name>Shaun Freeman</name></author><category term="Linux" /><category term="Nginx" /><summary type="html">I love Nginx as a webserver, it’s quick and easy to configure (if you know what you are doing). As a web developer (or should I say programmer), I like to make things as easy as possible in my development environment. As my projects have increased over time I have noticed my Nginx config growing to accommodate each project.</summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://localhost:4000/assets/img/nginx-logo.png" /><media:content medium="image" url="http://localhost:4000/assets/img/nginx-logo.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Gigabyte Brix BXBT-1900 Not Booting without Monitor on Ubuntu Minimal 16.04</title><link href="http://localhost:4000/gigabyte-brix-bxbt-1900-not-booting-without-monitor-on-ubuntu-minimal-16-04/" rel="alternate" type="text/html" title="Gigabyte Brix BXBT-1900 Not Booting without Monitor on Ubuntu Minimal 16.04" /><published>2016-12-14T16:12:48+00:00</published><updated>2016-12-14T16:12:48+00:00</updated><id>http://localhost:4000/gigabyte-brix-bxbt-1900-not-booting-without-monitor-on-ubuntu-minimal-16-04</id><content type="html" xml:base="http://localhost:4000/gigabyte-brix-bxbt-1900-not-booting-without-monitor-on-ubuntu-minimal-16-04/">&lt;p class=&quot;lead&quot;&gt;I love my Gigabyte Brix BXBT-1900, I have been running it as a headless server since March 2016 and had no problems with it I originally put Ubuntu 14.04 LTS and got to going quite easily. When Ubuntu 16.04 LTS I did an in situ update to Ubuntu 16.04 for which my MySQL keep breaking when Ubuntu kept adding updates for it, I have posted on this before http://www.shaunfreeman.name/ubuntu-16-04-mysql-update-fails/.&lt;/p&gt;

&lt;p&gt;I had noticed that a fresh install of Ubuntu 16.04 didn’t break the MySQL update so it must of been something that didn’t update well there.&lt;/p&gt;

&lt;p&gt;In my foolish fancy I though ‘Hey! Why not fresh install my Ubuntu server on my Brix BXBT-1900 to fix this’&lt;/p&gt;

&lt;p&gt;So that’s what I did, got my mini ISO version of Ubuntu 16.06.1 LTS and installed it a fresh on the BXBT-1900.&lt;/p&gt;

&lt;p&gt;Now as I use the Brix as a headless server I had to connect it to a monitor to install Ubuntu, so I attached it to my TV via the HDMI port. Every thing went well got it installed and installed ssh-server so I could SSH into it. I then shutdown the Brix and moved it back to it’s place, attached it back to the network and boots it up.&lt;/p&gt;

&lt;p&gt;Then came my shock. I couldn’t SSH in, looked in my router admin panel … not there!&lt;/p&gt;

&lt;p&gt;OK I moved it back to the TV and attached it back via the HDMI port and booted it up, watched it boot and everything looked OK, went to SSH in and Yea! I could. Tried it again without the TV attached and bosh! same old problem.&lt;/p&gt;

&lt;p&gt;So after a couple of hours messing around with BIOS settings and different ethernet cables and looking at the logs with no joy, it came to me that it seems to be hanging because there is on monitor. So maybe it’s not getting past grub or hanging just after waiting for a graphic display….&lt;/p&gt;

&lt;p&gt;OK lets look into the grub config file then and this is what is looked like. Open the config file with:&lt;/p&gt;

&lt;p&gt;sudo nano /etc/default/grub&lt;/p&gt;

&lt;p&gt;This is what mine looked like&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-nano&quot; data-lang=&quot;nano&quot;&gt;# If you change this file, run 'update-grub' afterwards to update
# /boot/grub/grub.cfg.
# For full documentation of the options in this file, see:
#   info -f grub -n 'Simple configuration'

GRUB_DEFAULT=0
GRUB_HIDDEN_TIMEOUT=0
GRUB_HIDDEN_TIMEOUT_QUIET=true
GRUB_TIMEOUT=10
GRUB_DISTRIBUTOR=`lsb_release -i -s 2&amp;gt; /dev/null || echo Debian`
GRUB_CMDLINE_LINUX_DEFAULT=&quot;splash quiet&quot;
GRUB_CMDLINE_LINUX=&quot;&quot;

# Uncomment to enable BadRAM filtering, modify to suit your needs
# This works with Linux (no patch required) and with any kernel that obtains
# the memory map information from GRUB (GNU Mach, kernel of FreeBSD ...)
#GRUB_BADRAM=&quot;0x01234567,0xfefefefe,0x89abcdef,0xefefefef&quot;

# Uncomment to disable graphical terminal (grub-pc only)
#GRUB_TERMINAL=console

# The resolution used on graphical terminal
# note that you can use only modes which your graphic card supports via VBE
# you can see them in real GRUB with the command `vbeinfo'
#GRUB_GFXMODE=640x480

# Uncomment if you don't want GRUB to pass &quot;root=UUID=xxx&quot; parameter to Linux
#GRUB_DISABLE_LINUX_UUID=true

# Uncomment to disable generation of recovery mode menu entries
#GRUB_DISABLE_RECOVERY=&quot;true&quot;

# Uncomment to get a beep at grub start
#GRUB_INIT_TUNE=&quot;480 440 1&quot;

OK now that doesn't look right to me for just a headless server lines

GRUB_CMDLINE_LINUX_DEFAULT=&quot;splash quiet&quot;
GRUB_CMDLINE_LINUX=&quot;&quot;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;and&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-nano&quot; data-lang=&quot;nano&quot;&gt;# Uncomment to disable graphical terminal (grub-pc only)
#GRUB_TERMINAL=console

shouldn't read like that, we want Ubuntu to boot in text mode thank you very much! so lets change them. So to boot a headless server the lines should read

GRUB_CMDLINE_LINUX_DEFAULT=&quot;&quot;
GRUB_CMDLINE_LINUX=&quot;text&quot;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;and&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-nano&quot; data-lang=&quot;nano&quot;&gt;# Uncomment to disable graphical terminal (grub-pc only)
GRUB_TERMINAL=console&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Once these where changed we have to update grub with&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;update-grub&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;I then shutdown the Brix and put it back in its little place, booted it up and Presto! I was able to SSH in!&lt;/p&gt;

&lt;p&gt;So if you are having boot problems with your headless server try looking at the grub config first it my save you several hours of head banging frustration..&lt;/p&gt;

&lt;p&gt;Watch on YouTube : &lt;a href=&quot;https://youtu.be/Be2hcL5bDR4&quot;&gt;How To Boot Ubuntu In Text Mode&lt;/a&gt;&lt;/p&gt;</content><author><name>Shaun Freeman</name></author><category term="Linux" /><category term="Ubuntu" /><summary type="html">I love my Gigabyte Brix BXBT-1900, I have been running it as a headless server since March 2016 and had no problems with it I originally put Ubuntu 14.04 LTS and got to going quite easily. When Ubuntu 16.04 LTS I did an in situ update to Ubuntu 16.04 for which my MySQL keep breaking when Ubuntu kept adding updates for it, I have posted on this before http://www.shaunfreeman.name/ubuntu-16-04-mysql-update-fails/.</summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://localhost:4000/assets/img/ubuntu_orange_st_hex.png" /><media:content medium="image" url="http://localhost:4000/assets/img/ubuntu_orange_st_hex.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Setting Up A Testing Environment For PHP Using VirtualBox - Part 2 Installing Ubuntu 16.04</title><link href="http://localhost:4000/setting-up-a-testing-environment-for-php-using-virtualbox-part-2-installing-ubuntu-16-04/" rel="alternate" type="text/html" title="Setting Up A Testing Environment For PHP Using VirtualBox - Part 2 Installing Ubuntu 16.04" /><published>2016-12-09T12:12:45+00:00</published><updated>2016-12-09T12:12:45+00:00</updated><id>http://localhost:4000/setting-up-a-testing-environment-for-php-using-virtualbox-part-2-installing-ubuntu-16-04</id><content type="html" xml:base="http://localhost:4000/setting-up-a-testing-environment-for-php-using-virtualbox-part-2-installing-ubuntu-16-04/">&lt;p class=&quot;lead&quot;&gt;In this second part of this tutorial I will show you how to install Ubuntu Server on your virtual machine in VirtualBox. You can take these principles and apply them to a physical machine but if you purchase a cloud instance you normally have all this done for you, so really this is good to know for our testing purposes.&lt;/p&gt;

&lt;h2 id=&quot;installing-ubuntu&quot;&gt;Installing Ubuntu&lt;/h2&gt;

&lt;p&gt;OK from the last tutorial you should have your virtual machine setup if not please go back to &lt;a href=&quot;http://www.shaunfreeman.name/setting-up-a-testing-environment-for-php-using-virtualbox-part-1-installing-virtualbox&quot;&gt;part 1&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To fire up the virtual server hightlight it and press the ‘Start’ button which should bring you to this screen&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/virtualbox/Capto_Capture-2016-12-06_11-29-30_am.png&quot; alt=&quot;Capto_Capture-2016-12-06_11-29-30_am.png&quot; class=&quot;img-fluid&quot; /&gt;&lt;/p&gt;

&lt;p&gt;If you are using VirtualBox for the first time you will receive these messages about mouse integration, what this is is when you click inside the window your mouse will work in the virtual machine and when you want to use your mouse on your desktop you have to release it by pressing the ‘host key’ in this case it is ‘Left cmd’ just check the ‘Do not show this message again’ and click capture and we are good to go.&lt;/p&gt;

&lt;p&gt;The menu displayed has a list of languages to choose from as we are doing this in English that’s what we highlight by pressing ‘Enter’ key if you want to change this use the directional keys on your keyboard to highlight the desired language and press ‘Enter’&lt;/p&gt;

&lt;p&gt;Next Press ‘F4’ to select ‘Modes’ option and use the down arrow key to select ‘Install a minimal virtual machine’ and press enter. We do this because we are not using physical hardware (if you then don’t use this option), then press enter to start the installation process.&lt;/p&gt;

&lt;p&gt;Next we have to choose a language which we are staying with english&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/virtualbox/Capto_Capture-2016-12-06_11-32-00_am.png&quot; alt=&quot;Capto_Capture-2016-12-06_11-32-00_am.png&quot; class=&quot;img-fluid&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Press enter and then we move on to ‘Select your location’&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/virtualbox/Capto_Capture-2016-12-06_11-32-36_am.png&quot; alt=&quot;Capto_Capture-2016-12-06_11-32-36_am.png&quot; class=&quot;img-fluid&quot; /&gt;&lt;/p&gt;

&lt;p&gt;It should guess where you are but if not just select your location and press enter.&lt;/p&gt;

&lt;p&gt;Next you have to configure your keyboard and will see&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/virtualbox/Capto_Capture-2016-12-06_11-33-22_am.png&quot; alt=&quot;Capto_Capture-2016-12-06_11-33-22_am.png&quot; class=&quot;img-fluid&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Here we have to configure are keyboard in which we have two options&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;let the software detect the language by press a series of keys&lt;/li&gt;
  &lt;li&gt;select keyboard layout manually&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;if you choose option 1 then you will be asked a series of questions in which you press the appropriate keys. If you choose option 2 then you have to choose from a list. Option 1 is the easiest if you are sure so press the left arrow key to highlight it and press enter.&lt;/p&gt;

&lt;p&gt;After your keyboard is set up it will load in some components and end up on the ‘Configure Network’ option like&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/virtualbox/Capto_Capture-2016-12-06_11-35-34_am.png&quot; alt=&quot;Capto_Capture-2016-12-06_11-35-34_am.png&quot; class=&quot;img-fluid&quot; /&gt;&lt;/p&gt;

&lt;p&gt;You can leave it with the ubuntu Hostname or change it to something else. This is the name your server will identify as. Press enter when done and we go to ‘Set up users and passwords’. In the first screen we have to put in our full name&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/virtualbox/Capto_Capture-2016-12-06_11-36-29_am.png&quot; alt=&quot;Capto_Capture-2016-12-06_11-36-29_am.png&quot; class=&quot;img-fluid&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Press enter and we go on to your username, this is the name we use to log into the server&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/virtualbox/Capto_Capture-2016-12-06_11-36-49_am.png&quot; alt=&quot;Capto_Capture-2016-12-06_11-36-49_am.png&quot; class=&quot;img-fluid&quot; /&gt;&lt;/p&gt;

&lt;p&gt;I just used my first name for this. Press enter and next we setup our password which we will use to log in to the server&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/virtualbox/Capto_Capture-2016-12-06_11-37-13_am.png&quot; alt=&quot;Capto_Capture-2016-12-06_11-37-13_am.png&quot; class=&quot;img-fluid&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Press enter when done and next you will have to confirm your password so when you have done that you will be asked whether you would like to encrypt your home directory, the default is ‘no’ so we just press enter&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/virtualbox/Capto_Capture-2016-12-06_11-38-41_am.png&quot; alt=&quot;Capto_Capture-2016-12-06_11-38-41_am.png&quot; class=&quot;img-fluid&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Next we confirm our time zone it should guess it correctly but if not you can choose from a list&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/virtualbox/Capto_Capture-2016-12-06_11-38-59_am.png&quot; alt=&quot;Capto_Capture-2016-12-06_11-38-59_am.png&quot; class=&quot;img-fluid&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Next we go on the patron the disk for this just choose the default ‘Guided - use entire disk’ and press enter&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/virtualbox/Capto_Capture-2016-12-06_11-39-21_am.png&quot; alt=&quot;Capto_Capture-2016-12-06_11-39-21_am.png&quot; class=&quot;img-fluid&quot; /&gt;&lt;/p&gt;

&lt;p&gt;then press enter again when you come to this screen&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/virtualbox/Capto_Capture-2016-12-06_11-39-35_am.png&quot; alt=&quot;Capto_Capture-2016-12-06_11-39-35_am.png&quot; class=&quot;img-fluid&quot; /&gt;&lt;/p&gt;

&lt;p&gt;When you come to this screen&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/virtualbox/Capto_Capture-2016-12-06_11-39-48_am.png&quot; alt=&quot;Capto_Capture-2016-12-06_11-39-48_am.png&quot; class=&quot;img-fluid&quot; /&gt;&lt;/p&gt;

&lt;p&gt;You have to tab onto &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;Yes&amp;gt;&lt;/code&gt; and press enter. then it will stall the system files. The next option is to use a Http proxy which we just leave it blank and press enter&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/virtualbox/Capto_Capture-2016-12-06_11-40-39_am.png&quot; alt=&quot;Capto_Capture-2016-12-06_11-40-39_am.png&quot; class=&quot;img-fluid&quot; /&gt;&lt;/p&gt;

&lt;p&gt;You will be asked if you want to configure the system with automatic updates and we just select the ‘No automatic updates’ and press enter.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/virtualbox/Capto_Capture-2016-12-06_11-41-07_am.png&quot; alt=&quot;Capto_Capture-2016-12-06_11-41-07_am.png&quot; class=&quot;img-fluid&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Next we have the Software selection which just use the down arrow key till you get to OpenSSH Server and press the space bar to select it and press enter to continue.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/virtualbox/Capto_Capture-2016-12-06_11-41-46_am.png&quot; alt=&quot;Capto_Capture-2016-12-06_11-41-46_am.png&quot; class=&quot;img-fluid&quot; /&gt;&lt;/p&gt;

&lt;p&gt;we have to wait while the package manager installs our selections the you will see this screen&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/virtualbox/Capto_Capture-2016-12-06_11-42-59_am.png&quot; alt=&quot;Capto_Capture-2016-12-06_11-42-59_am.png&quot; class=&quot;img-fluid&quot; /&gt;&lt;/p&gt;

&lt;p&gt;We have to select &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;Yes&amp;gt;&lt;/code&gt; and press enter. the boot loader will then install and then next screen should be ‘Finish the installation’&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/virtualbox/Capto_Capture-2016-12-06_11-43-19_am.png&quot; alt=&quot;Capto_Capture-2016-12-06_11-43-19_am.png&quot; class=&quot;img-fluid&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Press enter and the system should reboot into the login screen and we are done&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/virtualbox/Capto_Capture-2016-12-06_11-44-12_am.png&quot; alt=&quot;Capto_Capture-2016-12-06_11-44-12_am.png&quot; class=&quot;img-fluid&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Now you are ready to install some software to run a web server and install PHP which we will cover in the next part of this series.&lt;/p&gt;

&lt;p&gt;Any comments or questions please leave in the comments and happy coding!&lt;/p&gt;

&lt;p&gt;I have made a video on this part&lt;/p&gt;

&lt;p&gt;Watch on youtube: &lt;a href=&quot;https://www.youtube.com/watch?v=O5q44cFn5_E&quot;&gt;Setting Up A Testing Environment For PHP Using VirtualBox - Part 2 Installing Ubuntu Server&lt;/a&gt;&lt;/p&gt;</content><author><name>Shaun Freeman</name></author><category term="Linux" /><category term="Ubuntu" /><summary type="html">In this second part of this tutorial I will show you how to install Ubuntu Server on your virtual machine in VirtualBox. You can take these principles and apply them to a physical machine but if you purchase a cloud instance you normally have all this done for you, so really this is good to know for our testing purposes.</summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://localhost:4000/assets/img/virtualbox/PHP-tutorial-Part2.png" /><media:content medium="image" url="http://localhost:4000/assets/img/virtualbox/PHP-tutorial-Part2.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Setting Up A Testing Environment For PHP Using VirtualBox - Part 1 Installing VirtualBox</title><link href="http://localhost:4000/setting-up-a-testing-environment-for-php-using-virtualbox-part-1-installing-virtualbox/" rel="alternate" type="text/html" title="Setting Up A Testing Environment For PHP Using VirtualBox - Part 1 Installing VirtualBox" /><published>2016-12-09T07:12:53+00:00</published><updated>2016-12-09T07:12:53+00:00</updated><id>http://localhost:4000/setting-up-a-testing-environment-for-php-using-virtualbox-part-1-installing-virtualbox</id><content type="html" xml:base="http://localhost:4000/setting-up-a-testing-environment-for-php-using-virtualbox-part-1-installing-virtualbox/">&lt;p class=&quot;lead&quot;&gt;In this tutorial I will show you how to download and install VirtualBox for your development environment. This is a software virtualisation package which we install on our computer, and through VirtualBox we can then install other operating systems and run them ‘natively’. So we can run a Linux server on a Windows machine. We do this for a few reasons:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Every computer is different with regard to software, hardware and operating systems.&lt;/li&gt;
  &lt;li&gt;Differences with your computer and the target server can be reduced by mimicking the server and running our test code on our test server.&lt;/li&gt;
  &lt;li&gt;Cuts down the cost of not having to hire webspace or rent a cloud server.&lt;/li&gt;
  &lt;li&gt;Allows us to have the exact same server configuration as our as the target server.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;installing-the-required-software&quot;&gt;Installing the Required Software&lt;/h2&gt;

&lt;p&gt;To get our environment up and running we will need to first download the software from virtualbox.org, you should choose the binary that corresponds to your operating system. If you are running a Windows OS then click the Windows hosts link and if you are running OS X then click the OS X link, as I am using OS X then that’s the one I will download the download a copy of Ubuntu Server from &lt;a href=&quot;https://www.ubuntu.com/download/server&quot;&gt;https://www.ubuntu.com/download/server&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;creating-your-virtual-machine&quot;&gt;Creating your virtual machine&lt;/h2&gt;

&lt;p&gt;First install VirtualBox the usual way you instal programs on your computer, once installed start the program and you should see a window like&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/virtualbox/Capto_Capture-2016-12-06_10-40-43_am.png&quot; alt=&quot;Capto_Capture-2016-12-06_10-40-43_am.png&quot; class=&quot;img-fluid&quot; /&gt;&lt;/p&gt;

&lt;p&gt;To make your new virtual machine click ‘New’ and you will be presented with a new box entitled ‘Name and operating system’, fill the name out to ‘Ubuntu Server’ and ‘Type and ‘Version’ should be automatically selected like below, we want the ‘Type’ to be ‘Linux’ and the ‘Version’ to be ‘Ubuntu (64-bit)’ if they are not selected then go ahead an manually select them&lt;/p&gt;

&lt;p&gt;Next click ‘Continue’ and the next window entitled ‘Memory size’. This option is how much RAM we are to allocate to our Ubuntu Server the default is 1024MB so if you have quite a bit of RAM then you can add more but don’t go into the red area on the slider like below&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/virtualbox/Capto_Capture-2016-12-06_10-42-11_am.png&quot; alt=&quot;Capto_Capture-2016-12-06_10-42-11_am.png&quot; class=&quot;img-fluid&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Click ‘Continue’ and the next option is the ‘Hard disk’ make sure you have the ‘Create a virtual hard disk now’ and click ‘Create’&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/virtualbox/Capto_Capture-2016-12-06_10-42-33_am.png&quot; alt=&quot;Capto_Capture-2016-12-06_10-42-33_am.png&quot; class=&quot;img-fluid&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The next window is ‘Hard disk file type’ just keep the default option of ‘VDI (VirtualBox Disk Image)’ and click ‘Continue’&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/virtualbox/Capto_Capture-2016-12-06_10-42-53_am.png&quot; alt=&quot;Capto_Capture-2016-12-06_10-42-53_am.png&quot; class=&quot;img-fluid&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The next option is ‘Storage on physical hard disk’ this option is how much space the virtual hard drive will take up on your physical hard drive, I would leave it on the ‘Dynamically allocated’ option as this will grow the dark drive to it’s maximum limit you set, so if at the end of install the space taken by the files on the server is 3 GB then that’s the physical size the image on your hard drive will be and will grow up to the maximum.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/virtualbox/Capto_Capture-2016-12-06_10-43-05_am.png&quot; alt=&quot;Capto_Capture-2016-12-06_10-43-05_am.png&quot; class=&quot;img-fluid&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Click ‘Continue’ and and the next window is ‘File location and size’ here we define which folder to put our image the default is the name of our server which is fine and select how much space the hard drive will grow to the minimum is 8 GB but you can give to more if you wish.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/virtualbox/Capto_Capture-2016-12-06_10-43-39_am.png&quot; alt=&quot;Capto_Capture-2016-12-06_10-43-39_am.png&quot; class=&quot;img-fluid&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Click ‘Create’ and it will create the virtual machine. When done you should have something similar to the picture below&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/virtualbox/Capto_Capture-2016-12-06_10-44-08_am.png&quot; alt=&quot;Capto_Capture-2016-12-06_10-44-08_am.png&quot; class=&quot;img-fluid&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Just a few more settings to adjust and then it’s done, so with your Ubuntu Server selected click settings and in the new window entitled ‘Ubuntu Server - General’ click the ‘System’ icon and then the ‘Processor’ option if you have a quad core or more computer you can add more cpu resources to your virtual machine here as I have eight cpus I will increase this value to 4, but don’t increase passed the red area as this will just slow things down.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/virtualbox/Capto_Capture-2016-12-08_10-33-35_pm.png&quot; alt=&quot;Capto_Capture-2016-12-08_10-33-35_pm.png&quot; class=&quot;img-fluid&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Next click ‘Display’ icon and this option you can increase the video memory but as we are not using a desktop we can keep this low to say 12 MB&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/virtualbox/Capto_Capture-2016-12-06_11-22-13_am.png&quot; alt=&quot;Capto_Capture-2016-12-06_11-22-13_am.png&quot; class=&quot;img-fluid&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Next we have to add your Ubuntu live disk so we can install the system so click ‘Storage’ and select the ‘Empty’ disk icon under ‘Controller.IDE’ in the ‘Storage Tree’ panel then on the right under ‘Attributes select the disk icon and add the iso you downloaded from Ubuntu by selecting the ‘Choose Optical Disk File’ option.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/virtualbox/Capto_Capture-2016-12-06_11-20-35_am.png&quot; alt=&quot;Capto_Capture-2016-12-06_11-20-35_am.png&quot; class=&quot;img-fluid&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Just one more option to adjust so select the ‘Network’ icon and here we configure the network adapter the default is ‘NAT’ which means it will be allocated an IP on a new subnet of your network like ‘10.0.0.1’ but we want it on the same subnet as our host computer so change the ‘Attached To’ option to ‘Bridged Network’ and choose the name of your hosts network adapter, if you are using WiFI to connect to the router choose that or the Ethernet option&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/virtualbox/Capto_Capture-2016-12-06_11-19-26_am.png&quot; alt=&quot;Capto_Capture-2016-12-06_11-19-26_am.png&quot; class=&quot;img-fluid&quot; /&gt;&lt;/p&gt;

&lt;p&gt;And that’s it, click ‘OK’ and we are ready to power our virtual machine up.&lt;/p&gt;

&lt;p&gt;Installing the Ubuntu Server will be in part 2 of this series. I have made a video tutorial to company this series so if you would like to check it out.&lt;/p&gt;

&lt;p&gt;hope you enjoyed this tutorial and as always happy coding!&lt;/p&gt;

&lt;p&gt;Watch on youtube: &lt;a href=&quot;https://youtu.be/qM-96clLKU0&quot;&gt;Setting Up A Testing Environment For PHP Using VirtualBox - Part 1 Installing VirtualBox&lt;/a&gt;&lt;/p&gt;</content><author><name>Shaun Freeman</name></author><category term="Linux" /><category term="Ubuntu" /><summary type="html">In this tutorial I will show you how to download and install VirtualBox for your development environment. This is a software virtualisation package which we install on our computer, and through VirtualBox we can then install other operating systems and run them ‘natively’. So we can run a Linux server on a Windows machine. We do this for a few reasons:</summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://localhost:4000/assets/img/virtualbox/PHP-tutorial-Part1.png" /><media:content medium="image" url="http://localhost:4000/assets/img/virtualbox/PHP-tutorial-Part1.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">How to Install MySQL or MariaDB on CentOS 7</title><link href="http://localhost:4000/how-to-install-mysql-or-mariadb-on-centos-7/" rel="alternate" type="text/html" title="How to Install MySQL or MariaDB on CentOS 7" /><published>2016-11-15T18:11:11+00:00</published><updated>2016-11-15T18:11:11+00:00</updated><id>http://localhost:4000/how-to-install-mysql-or-mariadb-on-centos-7</id><content type="html" xml:base="http://localhost:4000/how-to-install-mysql-or-mariadb-on-centos-7/">&lt;p class=&quot;lead&quot;&gt;As of CentOS 7 the default database is MariaDB and a drop in replacement for MySQL and should be fine for most people but if you need MySQL, there are some features in MySQL and not in MariaDB and vice versa.&lt;/p&gt;

&lt;p&gt;So with that said following these steps should get you MySQL installed in no time! If you are OK with MariaDB then you can follow steps 2 - 3 only and this will install MariaDB.&lt;/p&gt;

&lt;h2 id=&quot;step-1---install-mysql-repository&quot;&gt;Step 1 - Install MySQL Repository&lt;/h2&gt;

&lt;p&gt;First we have to install the community repository with&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;wget http://repo.mysql.com/mysql-community-release-el7-5.noarch.rpm
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;to download the repository then&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;rpm &lt;span class=&quot;nt&quot;&gt;-ivh&lt;/span&gt; mysql-community-release-el7-5.noarch.rpm
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;step-2---install-mysql&quot;&gt;Step 2 - Install MySQL&lt;/h2&gt;

&lt;p&gt;to install it. Now we have to update yum with&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;yum update
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Once this is done we can install mysql client and server with&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;yum &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;mysql-server mysql
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;and now start MySQL with&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;systemctl start mysqld
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;step-3---secure-mysql&quot;&gt;Step 3 - Secure MySQL&lt;/h2&gt;

&lt;p&gt;Now we have MySQL installed and started we have to secure it by setting the root password, removing anonymous user accounts, disable the root login outside of localhost and remove the test databases. we do this with&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;mysql_secure_installation
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;and you will be presented with this&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MySQL
      SERVERS IN PRODUCTION USE!  PLEASE READ EACH STEP CAREFULLY!

In order to log into MySQL to secure it, we&lt;span class=&quot;s1&quot;&gt;'ll need the current
password for the root user.  If you'&lt;/span&gt;ve just installed MySQL, and
you haven&lt;span class=&quot;s1&quot;&gt;'t set the root password yet, the password will be blank,
so you should just press enter here.

Enter current password for root (enter for none):
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If you have had MySQL installed before then enter the root password here but if this is a clean install just press enter the next question will be&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Setting the root password ensures that nobody can log into the MySQL
root user without the proper authorisation.

Set root password? &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;Y/n] y
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We want to set a password for root so answer ‘y’ and add your password. After you have set your password you will be asked&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;By default, a MySQL installation has an anonymous user, allowing anyone
to log into MySQL without having to have a user account created &lt;span class=&quot;k&quot;&gt;for
&lt;/span&gt;them.  This is intended only &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;testing, and to make the installation
go a bit smoother.  You should remove them before moving into a
production environment.

Remove anonymous &lt;span class=&quot;nb&quot;&gt;users&lt;/span&gt;? &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;Y/n] y
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We want to answer yes as we don’t want anonymous users next question will be&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Normally, root should only be allowed to connect from &lt;span class=&quot;s1&quot;&gt;'localhost'&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;.&lt;/span&gt;  This
ensures that someone cannot guess at the root password from the network.

Disallow root login remotely? &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;Y/n] y
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We again want to answer ‘y’ to this as we don’t want root to be accessed from the outside world! Next we have&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;By default, MySQL comes with a database named &lt;span class=&quot;s1&quot;&gt;'test'&lt;/span&gt; that anyone can
access.  This is also intended only &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;testing, and should be removed
before moving into a production environment.

Remove &lt;span class=&quot;nb&quot;&gt;test &lt;/span&gt;database and access to it? &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;Y/n] y
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We answer ‘y’ again as we do not want the test databases left installed, we have no need of them and finally&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Reloading the privilege tables will ensure that all changes made so far
will take effect immediately.

Reload privilege tables now? &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;Y/n] y
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;we will be asked to reload the privilege tables which we do want to so ‘y’ again.&lt;/p&gt;

&lt;p&gt;With that done we can test our MySQL by logging into the mySQL shell with&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;mysql &lt;span class=&quot;nt&quot;&gt;-u&lt;/span&gt; root &lt;span class=&quot;nt&quot;&gt;-p&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;enter your password and you should see&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Welcome to the MySQL monitor.  Commands end with &lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; or &lt;span class=&quot;se&quot;&gt;\g&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;.&lt;/span&gt;
Your MySQL connection &lt;span class=&quot;nb&quot;&gt;id &lt;/span&gt;is 13
Server version: 5.6.35 MySQL Community Server &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;GPL&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;

Copyright &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;c&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; 2000, 2016, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type &lt;span class=&quot;s1&quot;&gt;'help;'&lt;/span&gt; or &lt;span class=&quot;s1&quot;&gt;'\h'&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;help. Type &lt;span class=&quot;s1&quot;&gt;'\c'&lt;/span&gt; to clear the current input statement.

mysql&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now we have MySQL 5.6.35 installed. Enter ‘q’ and press enter to quit the MySQL shell.&lt;/p&gt;

&lt;h2 id=&quot;step-4---updating-to-mysql-57x&quot;&gt;Step 4 - Updating to MySQL 5.7.x&lt;/h2&gt;

&lt;p&gt;As of writing this MySQL 5.7.x was released but this repo has has that turned off so the update MySQL to 5.7.x first we enable it by&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;nano /etc/yum.repos.d/mysql-community.repo
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;the entry we are looking is&lt;/p&gt;

&lt;div class=&quot;language-vim highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;mysql57&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt;community&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt;dmr&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
name&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;MySQL &lt;span class=&quot;m&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;7&lt;/span&gt; Community Server Development Milestone Release
baseurl&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;http&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;//&lt;/span&gt;repo&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;mysql&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;com&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/yum/&lt;/span&gt;mysql&lt;span class=&quot;m&quot;&gt;-5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt;community&lt;span class=&quot;sr&quot;&gt;/el/&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/$basearch/&lt;/span&gt;
enabled&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;
gpgcheck&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;
gpgkey&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/etc/&lt;/span&gt;pki&lt;span class=&quot;sr&quot;&gt;/rpm-gpg/&lt;/span&gt;RPM&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt;GPG&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt;KEY&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt;mysql
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Change the ‘enabled=0’ to ‘enabled=1’ like&lt;/p&gt;

&lt;div class=&quot;language-vim highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;mysql57&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt;community&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt;dmr&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
name&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;MySQL &lt;span class=&quot;m&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;7&lt;/span&gt; Community Server Development Milestone Release
baseurl&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;http&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;//&lt;/span&gt;repo&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;mysql&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;com&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/yum/&lt;/span&gt;mysql&lt;span class=&quot;m&quot;&gt;-5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt;community&lt;span class=&quot;sr&quot;&gt;/el/&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/$basearch/&lt;/span&gt;
enabled&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;
gpgcheck&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;
gpgkey&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/etc/&lt;/span&gt;pki&lt;span class=&quot;sr&quot;&gt;/rpm-gpg/&lt;/span&gt;RPM&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt;GPG&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt;KEY&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt;mysql
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Save and exit the editor and the update yum with&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;yum update
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Yum should now update MySQL to version 5.7.x totes this enter the MySQL shell again with&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;mysql &lt;span class=&quot;nt&quot;&gt;-u&lt;/span&gt; root &lt;span class=&quot;nt&quot;&gt;-p&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;and you should see some like this&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Welcome to the MySQL monitor.  Commands end with &lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; or &lt;span class=&quot;se&quot;&gt;\g&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;.&lt;/span&gt;
Your MySQL connection &lt;span class=&quot;nb&quot;&gt;id &lt;/span&gt;is 3
Server version: 5.7.17 MySQL Community Server &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;GPL&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;

Copyright &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;c&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; 2000, 2016, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type &lt;span class=&quot;s1&quot;&gt;'help;'&lt;/span&gt; or &lt;span class=&quot;s1&quot;&gt;'\h'&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;help. Type &lt;span class=&quot;s1&quot;&gt;'\c'&lt;/span&gt; to clear the current input statement.

mysql&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And that’s it we have now installed MySQL 5.7.x&lt;/p&gt;

&lt;p&gt;Watch on YouTube: &lt;a href=&quot;https://youtu.be/TW_Uw3JG2ao&quot;&gt;Installing MySQL on CentOS 7&lt;/a&gt;&lt;/p&gt;</content><author><name>Shaun Freeman</name></author><category term="Linux" /><category term="CentOS" /><category term="MariaDB" /><category term="MySQL" /><summary type="html">As of CentOS 7 the default database is MariaDB and a drop in replacement for MySQL and should be fine for most people but if you need MySQL, there are some features in MySQL and not in MariaDB and vice versa.</summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://localhost:4000/assets/img/centoslogo.png" /><media:content medium="image" url="http://localhost:4000/assets/img/centoslogo.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Ubuntu 16.04 mysql update fails</title><link href="http://localhost:4000/ubuntu-16-04-mysql-update-fails/" rel="alternate" type="text/html" title="Ubuntu 16.04 mysql update fails" /><published>2016-06-26T20:06:14+01:00</published><updated>2016-06-26T20:06:14+01:00</updated><id>http://localhost:4000/ubuntu-16-04-mysql-update-fails</id><content type="html" xml:base="http://localhost:4000/ubuntu-16-04-mysql-update-fails/">&lt;p class=&quot;lead&quot;&gt;We all been there when an update fails but with an LTS server version you would think this would be something the Ubuntu team would fix quickly.
Problem:&lt;/p&gt;

&lt;p&gt;Anyway I was updating my packages today and got this error:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;dpkg error processing package mysql-server-5.7 &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;--configure&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now apt seems to be broken after this. (boo hoo and aarrgghh) after a quick google search I found no nice solution my only option was to reinstall, but how do I do that when I can’t remove MySQL anymore.
Solution:&lt;/p&gt;

&lt;p&gt;The good news is this can be fixed but not in a nice way so first thing is to make a backup of your database see ‘&lt;a href=&quot;/a-quick-mysql-backup-and-restore/&quot;&gt;A Quick MySQL Backup And Restore&lt;/a&gt;’ on how to do this. When done you need to stop the current MySQL service with:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;systemctl stop mysql
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Then you need to remove the MySQL packages with:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;apt-get purge mysql-server mysql-client mysql-common mysql-server-core-5.7 mysql-client-core-5.7
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Once done make sure the MySQL directories&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;sudo rm&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-rf&lt;/span&gt; /etc/mysql /var/lib/mysql
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now run apt-get cleanup commands&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;apt-get autoremove
&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;apt-get autoclean
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Reboot your server and run apt update and reinstall MySQL with&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;apt update
&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;apt-get &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;mysql-server mysql-client
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Once done restore your databases. You will also need to rest all passwords on all database user accounts as this seem to clear them.&lt;/p&gt;

&lt;p&gt;I also didn’t recommend any saving of a customised ‘my.cnf’ as this seems to be the culprit that causing this error.&lt;/p&gt;

&lt;p&gt;Anyway hope this helps and the Ubuntu team fix this really annoying error. If anyone has any suggestions on a better fix please let me know.&lt;/p&gt;

&lt;p&gt;Thanks and happy coding.&lt;/p&gt;</content><author><name>Shaun Freeman</name></author><category term="Linux" /><category term="Server" /><category term="MySQL" /><summary type="html">We all been there when an update fails but with an LTS server version you would think this would be something the Ubuntu team would fix quickly. Problem:</summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://localhost:4000/assets/img/ubuntu_orange_st_hex.png" /><media:content medium="image" url="http://localhost:4000/assets/img/ubuntu_orange_st_hex.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry></feed>