Nomad PHPThe PHP Developer Stack for Building Chatbots (20.4.2018, 04:05 UTC)

July - EU
Presented By

Ashley Hutson
July 19, 2018
20:00 CEST

The post The PHP Developer Stack for Building Chatbots appeared first on Nomad PHP.

Link
blog.phpdevPreparing for Pentesting (@ Longhorn PHP 2018) (17.4.2018, 13:57 UTC)

At this year’s Longhorn PHP conference I’ll be presenting two talks: an updated version of my “Securing Legacy Applications” session and something new and a bit different for a conference primarily aimed at development topics. I’ll be giving a tutorial on the first day (April 19th) about penetration testing. For those not familiar with the topic, penetration testing is a common security practice where you make attempts to locate the flaws in an application, usually without knowledge of the code running underneath.

For a group that’s primarily focused on “building” rather than “breaking” it might be a bit of a mind shift but I hope to at least provide my attendees with the basic concepts and tools to try it out on their own applications. There have been several sessions recently that focus on securing the code but that’s only half of the equation.

So, if you’re going to be attending my tutorial, here are a few things that can help you hit the ground running when we start. There’ll be a brief introduction to some of the basic application security concepts but we’re not going to dive too deep into those. Instead, you’ll be attacking a series of challenges I’ve created to teach the basics.

Here’s how to prepare:

– Go over the OWASP Top 10 to be familiar with the common vulnerability types (hint: several are in the challenges)
– Grab the Community Edition of the PortSwigger Burp Suite tool. We’ll be using this to help solve some of the challenges
– Check out the PHP security cheat sheet, some of the top PHP security issues and this guide to building secure PHP applications

Don’t worry if you’re not a PHP security pro – that kind of knowledge isn’t required here. The topics we’ll cover are more from the security testing side and, as an added bonus can be used on any kind of web-based application – not just PHP ones!

I hope to see you on Thursday morning – we’re going to have some fun!

Link
Matthias NobackCombing legacy code string by string (17.4.2018, 07:00 UTC)

I find it very curious that legacy (PHP) code often has the following characteristics:

  1. Classes with the name of a central domain concept have grown too large.
  2. Methods in these classes have become very generic.

Classes grow too large

I think the following happened:

The original developers tried to capture the domain logic in these classes. They implemented it based on what they knew at the time. Other developers, who worked on the code later, had to implement new features, or modify domain logic, because, well, things change. Also, because we need more things.

For instance, when a developer comes in and has to modify some of the logic related to "sales orders", they will look for classes with that name in it, like the SalesOrder entity, the SalesOrders controller, service, manager, helper, table gateway, repository, etc. Before considering the option to add more classes, most developers will first consider adding a method to one of the existing classes. Especially if the code of this class hasn't been tested.

Since this is legacy code we're talking about, it's very likely that the code hasn't been tested (if it was tested, would it be legacy code?). So most likely they will end up modifying the existing class, instead of thinking about what they really need: an object that does exactly what they need.

This is how legacy classes end up being so very large. We add more and more to it (since the new functionality is "related" to the existing code after all). It explains why legacy code has the first characteristic I mentioned at the beginning of this post ("Classes with the name of a central domain concept have grown too large."). The second characteristic still deserves some explanation though ("Methods in these classes have become very generic.").

Methods become very generic

Once we decide to take an existing class and modify it, we first analyze the code that's in the class: the method, the properties; we've all learned to take the D.R.Y. ("Don't repeat yourself") principle into account, so we're scared of redoing anything that was already done. While scanning the existing code, we may find several of the ingredients we need for the task at hand. Well, the ingredients are often somewhat useful, but not entirely what we need.

This is a crucial moment, a moment we've often experienced, a moment we've always appreciated. However, it's a moment we should fear, a moment we should fight (pardon the dramatic tone). It's the moment we change a method to fit in with our current use case.

How is this usually achieved? Most often we use one of the following tactics:

  1. Add an extra parameter (a.k.a. a parameter flag), using which we can influence the behavior of the method. Of course we provide a sensible default parameter, for backwards compatibility:

    // The original method:
    public function findAllSalesOrders()
    {
        // some complicated SQL, *almost* what we need
    }
    
    // The modified method, with a parameter flag
    public function findAllSalesOrders($excludeFinishedOrders = false)
    {
        // ...
    }
    
    
  2. Call another method first (a.k.a. decoration). This method may do some of the work, and maybe let the original method do its original work afterwards.

    // The original method:
    public function findAllSalesOrders()
    {
        // some complicated SQL, *almost* what we need
    }
    
    // The new method, which decorates the original one:
    public function findOpenSalesOrders()
    {
        // call the original method
        $salesOrders = $this->findAllSalesOrders();
    
        return array_filter($salesOrders, function(SalesOrder $order) {
            return $order->isOpen();
        };
    }
    
    

Sometimes we even combine the two, making one method more generic, and calling it from a more specific one:

// The original method:
public function findAllSalesOrders()
{
    // some complicated SQL, *almost* what we need
}

// The modified method:
public function findSpecificSalesOrders(array $statuses = [])
{
    // some complicated SQL, can do anything we need
}

// The new method, which decorates the modified original one
public function findOpenSalesOrders()
{
    return $this->findSpecificSalesOrders([SalesOrder::STATUS_OPEN]);
}

Over time, the original methods become more generic. That is, they can be used in many different scenarios. At the same time, the classes containing these methods keep growing. Every time we need a slightly different method, we add it, and use one of the tactics described. Slowly the class becomes too large to remain manageable (see

Truncated by Planet PHP, read more at the original (another 3906 bytes)

Link
Matthias NobackExceptions and talking back to the user (10.4.2018, 09:12 UTC)

Exceptions - for exceptional situations?

From the Domain-Driven Design movement we've learned to go somewhat back to the roots of object-oriented design. Designing domain objects is all about offering meaningful behavior and insights through a carefully designed API. We know now that domain objects with setters for every attribute will allow for the objects to be in an inconsistent state. By removing setters and replacing them with methods which only modify the object's state in valid ways, we can protect an object from violating domain invariants.

This style of modeling domain aggregates (entities and value objects) results in methods that modify state, but only after checking if the change is allowed and makes sense, given the rules dictated by actual domain knowledge. In terms of code, these methods may make some simple assertions about the arguments passed to it: the number of things, the range of a number, the format of a string. When anything is wrong about a provided argument, the domain object simply throws an exception. If everything is okay, the changes will be accepted by modifying any attribute involved.

So exceptions in your (object-oriented) domain model are not merely meant to signal an exceptional situation. They can be used to prevent invalid or unsupported usage of an object. By offering well-named methods (with sensible parameters) for changing the object's state, and by being very precise about throwing exceptions when invalid use is imminent, you make your domain objects usable in only one way: the way that makes sense. This is the exact opposite of how your domain objects end up looking if you generate getters and setters for every attribute.

Using exceptions for validation

You might say that, given that the object protects itself from ending up in an in valid state, it basically validates itself. However, it won't be good for our application's usability if we'd use these domain-level exceptions as messages to the user. The thing is:

  • Exceptions get thrown ad hoc, whenever something threatens the consistency of the domain object. You can only catch one of these exceptions and turn it into an error message for the user. If the user tries to fix the issue by making a change, sending the form again, and they manage to get past this exception, there may be another exception just around the corner. This will be very frustrating for the user, as it will feel like trial-and-error.
public function processDelivery(int $quantity, string $batchNumber): void {
    if ($quantity <= 0) {
        /*
         * If the user triggers this exception, they have to resubmit,
         * which may trigger another exception further down the line...
         */
        throw new InvalidArgument(
            'Quantity should be more than 0.'
        );
    }

    if (empty($batchNumber) {
        throw new InvalidArgument(
            'This delivery requires a batch number.'
        );
    }

    // ...
}

  • Domain exceptions aren't always about validating the data the user provides. They often signal that something is about to happen that can't logically happen, like a state change that isn't allowed or conceptually possible. E.g. once an order has been cancelled, it shouldn't be possible to change its delivery address, because that makes no sense:
public function changeDeliveryAddress(...): void {
    if ($this->wasCancelled) {
        throw new InvalidState('You cannot change ...');
    }

    // ...
}

  • Exception messages may contain more information than you'd like to share with the user.
  • Validation errors often require internationalization (i18n). They need localization in the sense that numbers should be formatted according to the user's locale. Of course, they often need translation too. Exceptions aren't naturally usable for translation, because they contain special values hard-coded into their messages.
throw new InvalidArgument(
    'Product 21 has a stock level of 100, but this delivery has a quantity of 200.'
);

Translation needs a template message which will be translated, after which the variables it contains will be replaced by their real values.

So exceptions thrown to protect domain invariants are not validation messages all by themselves. They are there to prevent bad things from happening to your domain objects. They are not useful if what you want is talk back to the user. If you're looking for a dialogue with the user about what they're trying to achieve, you should be having it in a layer of the application that's closer to the user.

There are several options there

Truncated by Planet PHP, read more at the original (another 6127 bytes)

Link
Paul M. JonesThe Conquest Code of Conduct (9.4.2018, 13:50 UTC)

If you’re tired of SJW COCs in open-source projects, try this one on for size:

Conquest’s Second Law: “Any organization not explicitly right-wing sooner or later becomes left-wing.”

tl;dr: No Socialism or Social Justice.


All contributions and communication are welcome, so long as they do not (within this project space) espouse, entertain, advocate for, or otherwise positively discuss the political ideals associated with Social Justice, Progressivism, Communism, Socialism, Fascism, Marxism, or anything else generally reminiscent of any political philosophy to the left of Classical Liberals or Libertarians.

If you suspect or are subjected to criminal behavior within this project space, first notify the appropriate authorities; then, if you wish, you may notify the project owner. The project owner makes no promises in advance regarding accusations or complaints.

The project owner is the final arbiter on all contributions and communication within this project space.

Link
Voices of the ElePHPantInterview with Chris Hartjes (8.4.2018, 16:34 UTC) Link
Matthias NobackMocking the network (3.4.2018, 07:15 UTC)

In this series, we've discussed several topics already. We talked about persistence and time, the filesystem and randomness. The conclusion for all these areas: whenever you want to "mock" these things, you may look for a solution at the level of programming tools used (use database or filesystem abstraction library, replace built-in PHP functions, etc.). But the better solution is always: add your own abstraction. Start by introducing your own interface (including custom return types), which describes exactly what you need. Then mock this interface freely in your application. But also provide an implementation for it, which uses "the real thing", and write an integration test for just this class.

The same really is true for the network. You don't want your unit tests to rely on a network connection, or a specific web service to be up and running. So, you override PHP's curl_exec() function. Or, if your code uses Guzzle, you inject its Mock Handler to by-pass part of its real-life behavior. The smarter solution again is to introduce your own interface, with its own implementation, and its own integration test. Then you can prove that this implementation is a faithful implementation of the interface (contract) you defined. And it allows you to mock at a much more meaningful level than just replacing a "real" HTTP response with a recorded one.

Though this solution would be quite far from traditional mocking I thought it would be interesting to write a bit more about it, since there's also a lot to say. It does require a proper example though. Let's say you're writing (and testing) a piece of financial calculation code where you're doing a bit of currency-conversion as well. You need a conversion rate, but your application doesn't know about actual rates, so you need to reach out to some web service that keeps track of these rates. Let's say, you make a call to "exchangerates.com":

# ...

$response = file_get_contents('https://exchangerates.com/?from=USD&to=EUR&date=2018-03-18')
$data = json_decode($response);
$exchangeRate = (float)$data->rate ?? 1;

# use the exchange rate for the actual calculation
# ...

Yes, this is horrible. Testing this code and "mocking" the network call is only one of our problems. We have to deal with broken connections and responses, and by the way, this code doesn't even take into account most of the other things that could go wrong. Code like this that connects with "the big bad world" requires a bigger safety net.

The first thing we should do is (as always) introduce an interface for fetching an exchange rate:

interface ExchangeRateService
{
    public function getFor(string $from, string $to, DateTimeImmutable $date): float
}

We could at least move all that ugly code and stick it in a class implementing this interface. Such is the merit of setting up a "facade", which "provides a simplified interface to a larger body of code". This is convenient, and it allows client code to use this interface for mocking. At the same time though, we're hiding the fact that we're making a network call, and that things can go wrong with that in numerous ways.

Implement an Anti-Corruption Layer

The first thing we can and should do is protect ourselves from the bad (data) model which the external service uses. We may have a beautiful model, with great encapsulation, and intention-revealing interfaces. If we'd have to follow the weird rules of the external service, our model risks being "corrupted".

That's what Domain-Driven Design's "Anti-Corruption Layer" (ACL - a bit of a confusing name) is meant for: we are encouraged to create our own models and use them as a layer in front of an external service's source of data. In our case, the interface we introduced was a rather simple one, one that doesn't allow for proper encapsulation. And because of the use of primitive types, there certainly isn't a place for a good and useful API. Due to a quirk in the external service I didn't mention yet, if one of the currencies is EUR, it always needs to be provided as the second ($to argument).

It'll be a perfect opportunity for an ACL. Instead of dealing with an exchange rate as a rather imprecise float type variable, we may want to define it as an integer and an explicit precision. And instead of working with DateTimeImmutable, we'd be better off modelling the date to be exactly what we need, and encode this knowledge in a

Truncated by Planet PHP, read more at the original (another 3011 bytes)

Link
Adam CulpWhat is Enterprise Ready? (2.4.2018, 16:19 UTC)

First, let me clarify, this post is not about Star Trek and the starship we’ve all come to know. Further, this post is not to attack any one group, and rather is my (perhaps poor) attempt to help others gain some visibility into what large companies (Enterprises) do, or perhaps should, look for in software prior to using it.

The Backstory

I saw some rumblings over the weekend between various communities where members of one were accusing another of not being “Enterprise Ready”. Of course, the other quickly responded that their tools were already being used in that capacity, therefore, they were indeed “Enterprise Ready”. (If it swims like a duck, it must be a duck.)

Following this I saw many more statements from various folks saying, “We are Enterprise, and we use it, and it’s working fine.”, and “What is ‘Enterprise Ready’ in any way?”

I’m sorry folks, but just because a company “can” or “will” use a given tool doesn’t mean they “should”, and it certainly doesn’t mean a given tool is indeed ready for use in companies reporting to shareholders or having requirements to meet certain compliance thresholds.

The Risks

There are no definitive guidelines to clearly state what “Enterprise Ready” really means, and there are certainly no lists of which applications are, or are not, Enterprise Ready.

Sure, there are different regulations for security, legal, and financial compliances. But even these only scratch the surface and do not clearly define what can/should be used. Especially when it comes to the many open source software packages available.

In many ways, it can come down to what a company is comfortable with. How much risk they are open to accept. And in some cases, how much liability they are willing to ignore and/or absorb when things go sideways.

On other fronts, a companies choices are led by the future. Large enterprises try to plan ahead because they know it is hard to change later down the line. Choices made today are often carried for 10 to 20 years, so it is very important to ensure they do not get caught in the trap of using tools lacking support and/or no longer getting security updates.

How It’s Made

I consult, and work directly with, some of the largest companies in the world every day whom I consider “Enterprise” in size. Since there are no pre-made lists of tools that are definitely “Enterprise”, I will share what many of these companies look at when choosing a tool or software, prior to allowing it to be added to their portfolio for the next 10 years.

The Requirements List

So, off we go:

  • Licensing
    If software/code does not include a license, companies and developers can’t use it. Making code public doesn’t automatically make it open for others to use. By default all code is subject to copyright and private.

    Also, in the same vein, adding an open source license doesn’t mean everyone can use it. Each open source license carries certain criteria which can prevent companies from using the code behind them.So, be careful to understand the ramifications of the license applied to a software package.

  • Interoperability
    Enterprise level companies have lots of software/code. I often see 4+ million lines of code in applications, not including 3rd party code and frameworks. This means that libraries must be able to work together in order to be used.

    In PHP, the PHP-Fig has worked hard for many years in an attempt to create conventions that, if followed, allow PHP libraries and frameworks to work together more easily. Therefore, Enterprise level companies tend to use code that follows the many PSR standards set by this body. Meanwhile, tools that do not follow these standards, regardless of how awesome, are rejected by Enterprises.

    Ask yourself, why should a company create internally maintained wrappers to facilitate “vendor lock-in” when another library doesn’t require such things because it is already interoperable.

  • Lock-in
    If packages of code does not work well with other packages of code, and somewhat forces use of tools created by the same entity, this is known as “vendor lock-in”. Thinking back to the days before open source becoming viable for common use, and I

Truncated by Planet PHP, read more at the original (another 6648 bytes)

Link
Nomad PHPWin Big, Cache Out (1.4.2018, 20:15 UTC)

June - US
Presented By

Ashley Hutson
June 21, 2018
20:00 CDT

The post Win Big, Cache Out appeared first on Nomad PHP.

Link
Matthias NobackModelling quantities - an exercise in designing value objects (27.3.2018, 08:20 UTC)

I recently came across two interesting methods that were part of a bigger class that I had to redesign:

class OrderLine
{
    /**
     * @var float
     */
    private $quantityOrdered;

    // ...

    /**
     * @param float $quantity
     */
    public function processDelivery($quantity)
    {
        $this->quantityDelivered += $quantity;

        $this->quantityOpen = $this->quantityOrdered - $quantity;
        if ($this->quantityOpen < 0) {
            $this->quantityOpen = 0;
        }
    }

    /**
     * @param float $quantity
     */
    public function undoDelivery($quantity)
    {
        $this->quantityDelivered -= $quantity;
        if ($this->quantityDelivered < 0) {
            $this->quantityDelivered = 0;
        }

        $this->quantityOpen += $quantity;
        if ($this->quantityOpen > $this->quantityOrdered) {
            $this->quantityOpen = $this->quantityOrdered;
        }
    }
}

Of course, I've already cleaned up the code here to allow you to better understand it.

What happens here is: we have an order line, which keeps track how much of a certain product has been "ordered", and then how much of it has been "delivered" so far. It also keeps track of how much is currently still "open". Changes to these "delivered" and "open" quantities happens when we "process" a delivery, or "undo" a delivery.

I was reminded of a recent blog post by Nicolò Pignatelli where he quoted a question from another programming website. Adopted to the situation at hand:

Which variable type would you use for representing a quantity?

[ ] Integer

[ ] Float

[ ] String

It's a trick question, because all the answers are wrong. Nicolò advises not to use a primitive type value, but to design a value object that can represent a quantity. Nevertheless, in this code base it's floats everywhere.

I'm still modified-copycat-ing Nicolò's blog post here, since he's asking some really good questions that can guide your thinking about value objects:

  • Does it make sense to add or subtract two [quantities]? Maybe.
  • Does it make sense to multiply or divide two [quantities]. Don’t think so.
  • Does it make sense to allow negative [quantities]? Probably not.

You have to ask yourself these questions, since these properties would hold for a float, but not for quantities. Quantities can (sometimes) be added, but in the domain of selling and stock they should certainly not be divided (maybe multiplied against a tariff of some sorts, but then the result is not a quantity anymore). It also makes no sense to order a negative quantity, since that would be more like giving a quantity away.

This exposes quite nicely the need for modelling; the need for "codifying" the knowledge we have about quantities in our domain.

We may start out by wrapping these floats in a simple object called Quantity:

final class Quantity
{
    /**
     * @var float
     */
    private $quantity;

    public function __construct(float $quantity)
    {
        $this->quantity = $quantity;
    }
}

By the way, I find that it really helps to write unit tests along the way. You don't have to do pure TDD, but at least make tests part of your workflow. It'll be great, since every unit test method can help you document every one of your design criteria or decisions.

It's also a good idea to not just start re-implementing the algorithm you find in existing code, like the code above. Think about what's going on. Follow your intuition. For example, those if statements that end up "capping" certain quantities (to 0, or to the ordered quantity), are kind of iffy (pun intended).

Unraveling the meaning of these different quantities by thinking about them, and remembering something the domain expert said, I realized that:

  1. These quantities are related.
  2. These quantities aren't all of the same kind.
  3. The if statements hide some important domain knowledge.

The open quantity is what remains to be delivered. So it's the result of subtracting all the quantities that have been delivered from the initially ordered quantity. However, this doesn't take into consideration that we can "over-deliver", that is, we can deliver more than was ordered, and that's perfectly fine. That's why we need to cap the open quantity to 0: if we over-deliver, there's just nothing more that needs to be delivered, and we don't need to give something back. This explains the first if statement.

The other way around, if we undo a delivery,

Truncated by Planet PHP, read more at the original (another 6177 bytes)

Link
LinksRSS 0.92   RDF 1.
Atom Feed   100% Popoon
PHP5 powered   PEAR
ButtonsPlanet PHP   Planet PHP
Planet PHP