Right before the first dot.com bubble had burst, web developers wielding only Photoshop and an HTML editor were raking in $80k+ a year. When it all tanked, some of these developers went back to graphic design, got into project management, or rolled up their sleeves and learned the hard stuff – real programming.
You Don't Understand Object Oriented Design
You may have heard people talk about it or maybe have even learned it in school. If you don't understand the concept of a class outside of using it on a web page, time to do some homework. If you think inheritance or polymorphism is for those computer-science geeks, time to do some homework.
You Still Use Embedded SQL
Does sql = “select * from table where username = "” & request.form (“username”) sound familiar? If your code depends on concatenating SQL statements with user input, you"re headed for a world of pain. Sure, this is how all the programming books teach you how to database-enable your web application - for expediency sake. If you're not using stored procedures or even validating user input on the server side, you open yourself up to SQL injection attacks.
You Don't Understand Modular Design/Architecture
Is your application fifty miles wide and one inch deep? In other words, is your application fifty web forms sitting on top of a database, or do you have an intelligently designed business layer that is decoupled from your presentation layer? When all of your business logic lives on your form, your application is not extensible, testable, or reusable.
You Don't Unit Test
When you add new code to your site or application, how do you know it works? Do you load it up and click around and fiddle with it hoping that no errors pop up? Or do you sit back and rely on a set of unit tests to run and tell you whats wrong? How many times have you fixed one part of your code only to find that your “fix” broke something else?
For those who aren't familiar with unit tests, they're just little bits of code you write that attempt to use one part of your application and compare its outcome against a predefined correct value. If what it spits out and what you expect don't match, the test fails.
The beauty of unit testing is that its automated. Once you have an entire set of tests written - usually referred to as a test suite, you can execute them after every code change to determine what's broken in your application.
You Write the Same Code Over and Over Again
Do you write the same boilerplate database connection code on every new application you work on? At the very least you should have some basic libraries that you have compiled over the years that handle all the basics like data access, email, security, logging, etc. At some point you should have also looked into code generation to automatically generate a lot of basic code from a schema.
There you have it. From a programming standpoint, these concepts are fundamental and timeless. Before you run off and get mired in the next big thing, take time to make sure you're well rooted. Technologies come and go, but basic skills will yield a lot of mileage.