How to Get Laravel Debugging to work with PHPStorm and MAMP Pro 5
This has been one of the more aggravating things I’ve had to deal with in setting up software for development. I’ve followed the official documentation from JetBrains, over 30 other blog tutorials, and literally failed in getting any of them to work.
I figured out an easy way to make the setup work so I’m sharing it in case someone else finds it useful and for self-reference since I’ll probably forget how to do this again in 6 months when I start a new project.
MAMP Configuration
- Load MAMP and setup your host. Make note of the host name as you will need it to configure PHPStorm.
- Go to PHP on the left under Languages.
- On the right under Extensions, check Xdebug (Debugger).
PHPStorm Configuration
- Load PHPStorm and load your Laravel project.
- Setup your PHP executable and interpreter as per the official documentation and then resume here.
- On the top right of PHPStorm, select Edit Configurations from the dropdown.
- Click on the Plus Button on the top left of the dialog and then select ‘PHP Web Page’.
- Enter a descriptive name in the textbox. I use the host name from MAMP so it’s easy to identify visually. Click on the 3 dots with next to Server.
- Enter a descriptive name. I use the host name here as well. For the host, omit the http/https and just add the host name from MAMP.
- Click OK
- Now add your breakpoints and click on the Debugger Button on the top right and PHPStorm will load the site into the browser and break when breakpoints are hit.
Happy debugging!
(98)Address already in use: AH00072: make_sock: could not bind to address [::]:80 – error
I recently got handed a new Ubuntu droplet at work to setup and work on. I was going through the typical configuration to lock down the server and go to installing Apache when I suddenly ran into the error
(98)Address already in use: AH00072: make_sock: could not bind to address [::]:80 – error
I was a little surprised considering I had only run 4 commands total on a brand new installation. If you’re getting this error like me, you’ll need to find out what’s being bound to port 80 and then stop it. Use this command to get a list of anything that’s running on port 80.
sudo lsof -i:80
For me, it turned out nginx was running and bound to port 80. If you have the same problem, run this command to stop it:
sudo service nginx stop
Now you should be able to start apache.
How to Get Browser Name and Version via JavaScript
Today I ran into a strange issue where Firefox version 28 and below rendered style widths different than Firefox 29 and above. Firefox 29 and above appear to have fixed the issue and render sizes to match Chrome/IE8+/Opera/Safari. Unfortunately, as old as Firefox 28 is, our client’s legal review team is stuck on that version as IT refuses to let them upgrade. As such, we needed to add a kludge fix to the site to add a style to fix the issue for those running older Firefox versions. JQuery removed the version support from version 1.9 so here’s a handy script that will allow you to detect the browser and version without any extra dependencies.
function get_browser_info(){ var ua=navigator.userAgent,tem,M=ua.match(/(opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*(\d+)/i) || []; if(/trident/i.test(M[1])){ tem=/\brv[ :]+(\d+)/g.exec(ua) || []; return {name:'IE ',version:(tem[1]||'')}; } if(M[1]==='Chrome'){ tem=ua.match(/\bOPR\/(\d+)/) if(tem!=null) {return {name:'Opera', version:tem[1]};} } M=M[2]? [M[1], M[2]]: [navigator.appName, navigator.appVersion, '-?']; if((tem=ua.match(/version\/(\d+)/i))!=null) {M.splice(1,1,tem[1]);} return { name: M[0], version: M[1] }; }
Usage is very simple:
var browser=get_browser_info(); console.log(browser.name); console.log(browser.version);
BONUS: If you need to detect a specific version and add special classes, here’s a quick snippet that will allow you to add a class to the HTML tag using plain old vanilla.js.
var browser=get_browser_info(); if(browser.name == 'Firefox' && browser.version <= 28) { var root = document.documentElement; root.className += " firefox28"; }
SSL, jQuery, and CDN
I just got whacked by a minor bug with SSL and the Google CDN (totally my fault, not theirs). I stuck the reference to the CDN in my master page not realizing one of the pages would be served up as secured by the vendor due to compliance issues. It made it through all testing because none of the staging/dev environments were configured for SSL and I was not made aware of the fact that we’d be serving the page up through SSL. Internet Explorer 8 prompted users about the insecure content before rendering the page. In their infinite wisdom, Microsoft decided to implement a new workflow for insecure content where the content is ignored and the page renders immediately with the unsecured content ignored. Since jQuery was used on multiple parts of the form, the site essentially broke. Google Chrome and Firefox seem to recognize the CDN as a trusted source and render the page as expected.
To fix the site, I added a javascript check to set the appropriate prefix to the CDN call:
<script>// <![CDATA[ var gaJsHost = (("https:" == document.location.protocol) ? "https://" : "http://"); document.write(unescape("%3Cscript src='" + gaJsHost + "ajax.googleapis.com/ajax/libs/jquery/1.4.3/jquery.min.js' type='text/javascript'%3E%3C/script%3E")); // ]]></script>
{Unable to evaluate expression because the code is optimized or a native frame is on top of the call stack.}
Problem
If you’re working in ASP.NET and ever ran into the error:
{Unable to evaluate expression because the code is optimized or a native frame is on top of the call stack.}
You’ll probably find that the stack trace gives you no useful information as to where the error actually occurred.
The Solution
For Response.Redirect, use the overload function (Response.Redirect(String url, bool endResponse)) and pass false into the EndResponse parameter:
[csharp]Response.Redirect ("nextpage.aspx", false);[/csharp]
For Response.End, you’ll need to call the HttpContext.Current.ApplicationInstance.CompleteRequest method instead of Response.End to bypass the code execution to the Application_EndRequest event.
Details
The error occurs when you use Response.End, Response.Redirect, or Response.Transfer.The Response.End method ends the page execution and shifts the execution to the Application_EndRequest event in the application’s event pipeline. The line of code that follows Response.End is not executed. This problem occurs in the Response.Redirect and Server.Transfer methods because both methods call Response.End internally.
Detecting ASP.NET debug mode
The Problem
Recently I ran into a situation where I needed to debug ASP.NET code in a production environment that we had no control over. The server was managed by a third party support team and we deployed to a staging environment through a custom web deployment utility they built.
Of course, the code ran locally and on our internal staging environments with no issues but when deployed to the client’s remote staging servers, the application was encountering odd errors that we couldn’t replicate.
At this point, I wanted to add code to the web application that could be turned on and off without having to recompile deploy new dlls because of code changes in the code behind. With this particular client, code changes would trigger security scans that took over a week to complete and we were short on time.
The Solutions that Should’ve Worked but Didn’t.
Page Tracing wasn’t working. I remembered the #if Debug and HttpContext.Current.IsDebuggingEnabled statements worked rather well in other projects.
So I added:
#if Debug //Debug code here #endif
to the web application. Nothing happened so I tried:
if(!HttpContext.Current.IsDebuggingEnabled)
but it kept returning false even though debug mode was set to true in the web.config file.
The Solution (that worked!)
Finally I got the bright idea to read out the debug setting out of the web.config and execute code if the debug flag was set to true. How to do so wasn’t exactly obvious though.
After some searching, I finally figured it out and here’s the code snippet that will execute only if the debug flag is set to true:
System.Web.Configuration.CompilationSection cfg = (System.Web.Configuration.CompilationSection)ConfigurationManager.GetSection("system.web/compilation"); if (cfg.Debug) { Response.Write(ex.ToString()); }
Why Didn’t the Normal Debug Statements Work?
The issue was that the machine was configured as production. The machine.config overrode the web.config since the <deployment retail=”true”/> switch was set in Machine.config.
This setting disables Page.Tracing & #If Debug and always sets the IsDebuggingEnabled to false. This was done by Microsoft as a security precaution for companies so they could ensure no applications were deployed with debugging enabled by mistake.
Bonus! How Do I Loop Through All Session Variables in C#?
I wanted to see what the session variable values were during execution of the page with the caveat that it would only run if the debug flag was set to true.
<% System.Web.Configuration.CompilationSection cfg = (System.Web.Configuration.CompilationSection)ConfigurationManager.GetSection("system.web/compilation"); if (cfg.Debug) { for(int i = 0; i < Session.Contents.Count; i++) { Response.Write(Session.Keys[i] + " - " + Session[i] + "<br />"); } } %>
I added the code directly to the bottom of the aspx page since I didn’t want to modify the code behind and voila! Once the code was added to the page, we found that the expected session variables weren’t populating correctly on the remote server. Unfortunately it required a code change to resolve the issue but I never would have found the cause without the above snippet of code.