PHP: The latest news in the PHP world

5 readers
1 users here now

Share and discover the latest news about the PHP ecosystem and its community. Please respect r/php's rules.

founded 1 year ago
MODERATORS
1
 
 
The original post: /r/php by /u/Mont20- on 2024-12-27 01:39:11.
2
 
 
The original post: /r/php by /u/Alpine418 on 2024-12-26 19:42:49.

Hi folks.

I'm a PHP dev in my spare time. I already know Slim Framework, which fits my small needs perfectly. Everything is fine, but until now I couldn't find any "slim" ORM to get rid of pure SQL aka QueryBuilder statements with some dummy ORM logic created by myself.

So my questions to you pro PHP devs in here: Is there a simple and "slim" ORM that matches the slimness patterns without a lot of magic? Or what data handling solution do you prefer when working with Slim or other small frameworks?

Thanks in advance.

3
 
 
The original post: /r/php by /u/MagePsycho on 2024-12-26 19:15:12.

Just wondering, how do you create a composer patch file for project under ./vendor packages?

Is it something like:

# Manually stage specific files
git add -f ./vendor/{vendor}/{package}/file1.php ./vendor/{vendor}/{package}/file2.php ...

# Perform required changes on files
# ... (manual editing)

# Create patch manually
git diff ./vendor/{vendor}/{package}/file1.php ./vendor/{vendor}/{package}/file2.php ... > patches/{patch-name}.patch

# Cleanup steps
git restore ./vendor/{vendor}/{package}/file1.php ./vendor/{vendor}/{package}/file2.php ...
git reset HEAD ./vendor/{vendor}/{package}/file1.php ./vendor/{vendor}/{package}/file2.php ...

# OR
# If you are using diff command
# cp ./vendor/{vendor}/{package}/file.php ./vendor/{vendor}/{package}/file.php.old
# {perform required changes on file.php}
# diff -u ./vendor/{vendor}/{package}/file.php.old ./vendor/{vendor}/{package}/file.php > patches/{patch-name}.patch
# rm ./vendor/{vendor}/{package}/file.php
# mv ./vendor/{vendor}/{package}/file.php.old ./vendor/{vendor}/{package}/file.php

# Manually update composer.json
# "extra": {
#     "patches": {
#         "{vendor}/{package}": {
#             "{patch-message}": "patches/{patch-name}.patch",
#         },
#     }
# }

# Finally, apply patches
composer install

What if we automate this lengthy manual process with a simple bash script?

4
 
 
The original post: /r/php by /u/Holonist on 2024-12-26 18:11:22.
5
 
 
The original post: /r/php by /u/noweh95 on 2024-12-26 17:47:19.
6
1
Yii news 2024 (opencollective.com)
submitted 1 day ago by [email protected] to c/[email protected]
 
 
The original post: /r/php by /u/sam_dark on 2024-12-26 14:31:57.
7
 
 
The original post: /r/php by /u/Prestigiouspite on 2024-12-26 14:14:37.

I knew that CodeIgniter is faster than Laravel. But Leaf also sees Interesting from my point of view.

8
 
 
The original post: /r/php by /u/lazyk1ller on 2024-12-26 08:50:27.

i tried searching for some advanced php but most of them are just advanced programming concepts, i know those, i know design patterns, OOP, functional programming, clean code and all that jazz, im looking for learning advanced parts of PHP in particular, stuff like: overloading, magic methods, reflection, lazy classes, attributes, different extensions for processing image, cryptography and stuff along this lines.

im aware of the PHP manual but some examples there are not super clear, i would like something that explains stuff better

i would appreciate any type of resource but i prefer reading.

thanks in advnaced

9
 
 
The original post: /r/php by /u/RegularSuccessful124 on 2024-12-26 08:34:51.

Hi all,

I need to create, for personal purposes, a small web application. The usage is very basic: It has to select/insert/update from a MySQL database through web pages.

What is the best language to do this? 20 years ago, I used PHP to do this. Is it still reveleant?

If yes, which framework should I use to make the process easier, especially the database connection? In the past, I made everything by myself.

Thanks for any answer,

Best regards,

asx

10
 
 
The original post: /r/php by /u/fivefilters on 2024-12-25 21:09:56.
11
 
 
The original post: /r/php by /u/2019-01-03 on 2024-12-25 16:13:53.

https://github.com/hopeseekr/PrisonersDilemma

It uses phpexperts/php-evolver, which is a drop-dead simple way to create and use genetic algorithms in your own application.

What is the Prisoner's Dilemma?

  • Two criminals commit a crime but there's no evidence tying either to it.
  • Cops interrogate both separately.
  • If one rats on the other, they get no jail time and the other gets 5 years.
  • If both of them rat, they both get 2 years each.
  • If none of them rat, they will get the default 1 year.

In neither case do they know this beforehand, in most experiments.

I used phpexperts/php-evolver to test this with genetic algorithms, and it shows that overtime, populations will tend towards cooperation after about 120 generations.

Your partner's decision: They said nothing.  
Minimum Wage: $10 Outcomes:  
 \- You were convicted for 1 years.                Income: $40,000  
 \- Your partner was convicted for 1 years.        Income: $40,000  
Total Income: $80,000  
=== Generation 140 ===  
Protagonist Fitness: 120000

So how do you make a genetic algorithm in PHP? Well, most solutions are super hard, the phpexperts/php-evolver is pretty straight-forward.

First, you need to create the Creature (DNA interpretrations of the Genome) for your creatures. In Genetic Algorithm parlance, this is called "A Solution".

class PeopleFitnessSolution extends Solution
{
    const TEMPERMENT_NAIVE = 0;
    const TEMPERMENT_SELFISH = 100;

    public function genome()
    {
        // Like all real-world genomes, most GA genomes aren't semantically indexed either.
        return [
            ['integer', -200, 200], // Action/Decision Weight; upper and lower bounds
        ];
    }

    public function evaluate($fitness)
    {
        if (!($fitness instanceof PersonFitnessScore)) {
            dd($fitness);
            throw new \LogicException('Something is messed up. Corrupted entity.');
        }

        return $fitness->getFitnessScore();
    }
}

You define the genome with weight ranges (in this case, where they are from an angel (-200) to psychopath (200)).

And then you tie in the genome with the FitnessScore evaluator.

I decided to solve the prisoner's dilemma based upon how much minimum wage income could be gained (or lost) depending on how many years each convict spent in prison, basically $10,000/year free.

I used phpexperts/simple-dto to store the individual's selfishness range, the collective's earnings, and the individual's earnings.

use PHPExperts\SimpleDTO\SimpleDTO;

/**
 * u/property float $individualWages
 * u/property float $communityWages
 * @property float $selfishWeight    1.0 == 100% selfish, don't care about community.
 *                                   > 1.0 == Sociopathic. Antipathy.
 *                                   < 0.0 == Pathologically altruistic (Group > Self)
 */
class PersonFitnessScore extends SimpleDTO
{
    public function getFitnessScore()
    {
        return $this->individualWages + ($this->communityWages -  ($this->communityWages * $this->selfishWeight));
    }
}

Next you need to design the game itself, or what the Creatures are going to do over and over again, generation after generation. These are called "Decisions" in GA parlance.

Each decision should produce a tangible, quantifiable result in the overall envrionment of the game, so that the creatures can be evaluated at each term as closer or further from the goal.

class SuspectDecision
{
    // @todo ADD support for "Lawyering up".
    public const CONFESS = 0;
    public const TESTIFY = 1;
    public const SILENCE = 2;

    // @todo: Research whether this should be a constant or evolvable.
    public const POSSIBLE_DECISIONS = [
        self::CONFESS => 'Confess',
        self::TESTIFY => 'Testify against your partner',
        self::SILENCE => 'Say nothing',
    ];

    public static function isValidDecision(int $decisionId): bool
    {
        return array_key_exists($decisionId, self::POSSIBLE_DECISIONS);
    }

    /**
     * Returns a third-person response for a chosen decision.
     */
    public static function getThirdPartyResponse(int $decisionId): string
    {
        $DECISIONS = [
            self::CONFESS => 'They confessed to everything',
            self::TESTIFY => 'They testified against you',
            self::SILENCE => 'They said nothing',
        ];

        if (!array_key_exists($decisionId, $DECISIONS)) {
            throw new \LogicException("Invalid Partner Decision: $decisionId");
        }

        return $DECISIONS[$decisionId];
    }
}

Then you need to create a Genome for each type of Creature. This will determine how the genes each express themselves. In this case, we only have one gene, selfishness, so it's pretty simple.

class SuspectGenome
{
    public array $actions = [];
    public int $actionWeight = 0;
    public float $selfishWeight = 0;

    public function __construct(array $actions = [], int $actionWeight = 0, int $selfishWeight = 0)
    {
        $this->actions = $actions;
        $this->actionWeight = $actionWeight;
        $this->selfishWeight = $selfishWeight;
    }

    public function rememberAction(int $actionId, string $actionDescription)
    {
        // @todo: Should probably add error handling if the action doesn't actually exist.
        $this->actions[$actionId] = $actionDescription;
    }
}

The rest of the code, in the State directory, basically just is the programming of the game. Good Genetic algorithms will be playable games, usually, first. You can actually play the Prisoner's Dilemma yourself using this app.

Putting it all into action is the evolve:classic Laravel command:

All beautiful code resembles stories, and the most beautiful code can be easily read and understood like a novel by people with no coding experience. This Command is a good example.

Three actors in the story:

        $interrogator = new Interrogator();
        $protagonist = new Suspect($protagonistGenome);
        $partner = new Suspect($antagonistGenome);

Two separate interrogations and their outcomes:

        $protagonistChoice = $interrogator->interrogate($protagonist);
        $partnerChoice = $interrogator->interrogate($partner);

A fourth actor comes in, the Judge.

        $criminalLaw = new PrisonSentence();
        $judge = new Adjudicator($criminalLaw);

Both convicts can be tried either individually or together, just like our current legal system.

        $convictions = $judge->issueSentence($protagonistChoice, $partnerChoice);

The judge reads out to the court the maximum possible sentence.

        $maxPossibleSentence = $criminalLaw->getMaxSentence();

Then someone in accounting calculates how much income you both would earn individually based upon your prison sentences of 0, 1, or 5 years.

        $yourIncome = IncomeCalculator::calculate($hourlyWage, $maxPossibleSentence - $convictions['you']);
        $antagonistIncome = IncomeCalculator::calculate($hourlyWage, $maxPossibleSentence - $convictions['partner']);

This is packaged into a GA FitnessScore:

        $yourFitnessDTO = new PersonFitnessScore([
            'individualWages' => $yourIncome,
            'communityWages'  => $yourIncome + $antagonistIncome,
            'selfishWeight'   => $protagonistGenome->selfishWeight,
        ]);

        $theirFitnessDTO = new PersonFitnessScore([
            'individualWages' => $yourIncome,
            'communityWages'  => $yourIncome + $antagonistIncome,
            'selfishWeight'   => $antagonistGenome->selfishWeight,
        ]);

SimpleDTO acts as a sort of police agent, in that it assures that the prison sentence and community wages and psycho profile are all carried out through the simulation.

Finally, this entire play is done again, and again and again for 500 generations, pausing 222 ms between rounds so the human proctor (you!) can observe it in action.

    for ($generation = 1; $generation <= 500; ++$generation) {
        /** @var PersonFitnessScore $yourFitnessDTO */
        /** @var PersonFitnessScore $theirFitnessDTO */
        [$convictions, $yourFitnessDTO, $theirFitnessDTO] = $this->runRound($protagonistGenome, $antagonistGenome);

        $myFitness = $yourFitnessDTO->getFitnessScore();
        $theirFitness = $theirFitnessDTO->getFitnessScore();

        $cp = new ConsolePainter();
        $this->line($cp->onRed()->white()->bold("  === Generation $generation ===  "));
        $this->line($cp->onDarkGray()->white()->bold("  Protagonist Fitness: $myFitness\n" . json_encode($protagonistGenome, JSON_PRETTY_PRINT)));
        $this->line($cp->onDarkGray()->red()->bold("  Antagonist Fitness: $theirFitness\n" . json_encode($antagonistGenome, JSON_PRETTY_PRINT)));

        usleep(222222);
    }

It uses phpexperts/console-painter to create very nice colorized displays.

12
 
 
The original post: /r/php by /u/grandFossFusion on 2024-12-25 12:52:13.

Would you like it or not?

13
 
 
The original post: /r/php by /u/plonkster on 2024-12-25 12:25:53.

I'm by no mean a PHP wizard, matter of fact I'm primarily a C developer and never wrote PHP professionally so I have a naive question for the people in the know.

I've been only writing PHP outside of frameworks, depending solely on things such as PHP extensions or system libraries packaged in Debian-stable. This pretty much reduced my security concerns to how much I trust Debian-stable, and that trust was always relatively high, as far as I'm concerned.

Recently, I started pondering refactoring an old web site of mine, written in 2001. It's been running since then without issues. It is still used by a few tens of thousands of accounts every month and has a lot of user-facing surfaces - dealing with all kinds of user input and whatnot. Over the years I ported it to PHP8, but it's mainly old code written 25 years ago when PHP4 was all the rage.

So I figured, might as well do something useful and redo the whole thing over the course of a few months on and off, and learn Laravel at the same time. I was already savoring all the new things I was going to learn and how I was going to be able to delegate all the boring stuff such as user auth, logging, DB, sessions to Laravel, while concentrating on the fun stuff.

So off I go, read up on Laravel, and follow their Chirper tutorial by doing a composer create-project laravel/laravel chirper

It pulls down a few files and I'm all pumped about how I'm going to redo the site with all the modern bells and whistles, websockets, reactivity, and how it's going to be so much better.

Then, in the newly created project, I take a look in the vendor directory.

39 different directories. A find -type f . | wc -l says there are 8123 files that take 78 megabytes.

Now a honest and probably very naive question - am I supposed to feel safe about including all that code with autoload.php, or should I be worried, and if so - to which extent? Are those packages checked for security by some teams?

I tried to Google around and it looks like anyone can just submit a package to packagist. Now, for example, I'm looking at the file chirper/vendor/laravel/framework/composer.json and see all the requirements, for example tijsverkoyen/css-to-inline-styles": "^2.2.5" (just picked one randomly). If I understand correctly, that means "use that package of version 2.2.5 or higher, as long as its major version is 2.

Does it mean, that if tomorrow that user's (tijsverkoyen) packagist account gets compromised in some way, and a malicious user releases a 2.2.6 version of the package that contains a backdoor, new installations of Laravel all over the world will happily pull and use that version, at least until it gets noticed and removed from packagist? Or is there some validation mechanism in place that prevents that?

Thanks for enlightening me.

14
 
 
The original post: /r/php by /u/Sensitive-Raccoon155 on 2024-12-25 06:09:38.

Is it worth learning php instead of C# for backend development ?

15
 
 
The original post: /r/php by /u/newfnewfnewf on 2024-12-24 19:30:27.

I have a job right now but I am overworked and underpaid. I really don't like my employer because they don't respect me. This is my first actual job outside of freelance stuff and i've been here for 4 years, its time to move on.

But job searching terrifies me. What is the market like right now? Is the job market so bad right now that it is worth staying with a company that i'm unhappy with?

I am a php developer with 7 years experience who mostly does backend but can do front end as well. I am also dipping my toes into a lot of devops lately.

16
 
 
The original post: /r/php by /u/demonshalo on 2024-12-24 16:23:28.

Hey guys,

I'm planning on adding some "free tools" to my site but I know they're going to get abused by random bots or malicious users and want to restrict access to a reasonable number of executions (say X per hour or something).

Thing is, I'm trying to find a reasonable way to identify the user without relying on cookies or IP address, etc as these are all easily ignored. Are there any good standardized fingerprint libraries you know of that can help with that? Would appreciate any recommendations you might have.

Thanks

17
 
 
The original post: /r/php by /u/predvoditelev on 2024-12-24 13:20:49.
18
 
 
The original post: /r/php by /u/oguzhane on 2024-12-24 11:29:50.

https://oguzhankrcb.medium.com/introduction-to-symfony-microservice-architecture-with-grpc-communication-9ff08a23af4a

Hello all!

I wanted to share my new article: 'Introduction to Symfony Microservice architecture with gRPC communication'

19
 
 
The original post: /r/php by /u/davorminchorov on 2024-12-24 10:43:56.
20
 
 
The original post: /r/php by /u/gaufde on 2024-12-23 18:08:38.

I'm playing around with running Composer in a container rather than having it installed directly on my development machine. This seems to be a pretty popular thing to do, but I'm having trouble getting it working without some sort of undesirable behavior. I'd like to have a discussion about methodologies, so I'll describe what I've done to kick things off.

Here is the method I am trying. First, I have created a Containerfile so that I have some extra control over the image that will run Composer:

FROM php:8.2-fpm-alpine

ADD --chmod=0755 https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions /usr/local/bin/

RUN install-php-extensions \
    gd \
    zip \
    @composer-2.8.4

Then, after I've built the above image, I set up an alias in my shell to make it easy to run:

alias composer='podman run --rm \
--volume "$PWD:/app" \
--volume "${COMPOSER_HOME:-$HOME/.composer}:/var/www/html/.composer" \
--user $(id -u):$(id -g) \
localhost/local/composer composer'

Note: because I am on MacOS, Podman is running in a linux VM using the default podman machine mechanism which runs Fedora Core OS.

This works pretty well; however .composer directories keep getting created and left in my working directory after I run a composer command. I'm assuming that I don't have Composer's caching mechanisms configured correctly, but I have yet to figure that out.

So, my question is, how do other people set this up for themselves on their local development machines? Also, why do you do it using the method you have chosen?

21
 
 
The original post: /r/php by /u/ManuelKiessling on 2024-12-23 16:22:03.

Hi everyone,

I’m working on a business idea centered around selling a software toolkit for the PHP/Symfony ecosystem.

In the past, I fell into the common trap of focusing too much on the fun part — coding and building — only to end up with a product that lacked a real market need. This time, I’m determined to approach things differently. My goal is to validate whether there’s genuine interest in what I’m planning to offer, instead of creating a solution in search for a problem.

That’s where you come in! I’d love your feedback on whether this idea has potential or if it’s fundamentally flawed.

Here’s the gist:

I’m creating a pay-once, use-forever Software Development Starter Kit designed to give developers a solid foundation for building mid- to large-sized Symfony projects. While the concept itself isn’t unheard-of, I believe it can deliver substantial value by addressing common pain points.

The product offers three key benefits:

1. Batteries-Included Code Base

All the tedious setup work and low-level configurations are taken care of. The Starter Kit includes:

Pre-configured tools like PHP-CS-Fixer, PHPStan, and Tailwind (with dark/light theme switching).

Features such as a responsive app shell, i18n with multi-language SEO URLs, a language switcher, and a living style guide.

A robust test setup, including end-to-end testing with Panther.

Fully implemented user flows: sign up, sign in, forgot password, social login, "Magic Link" login, and more.

Advanced setups like organization/team management (including fully implemented "invite teammember" functionality"), a working Symfony Messenger setup, Stripe integration, and OpenAI/GPT model support.

2. Sensible Code Structure

Instead of leaving you with a mishmash of tools and features, the kit provides a clean, organized architecture, a feature-based structure across four layers: Domain, Infrastructure, Presentation, and API. What this means is that everything related to a specific application feature is contained in its own feature folder that sorts the feature's implementation into the aforementioned four layers, making the codebase easier to grow and maintain.

3. Sample Code, Tutorials, and Documentation

The kit comes with best-practice implementations of common features to jump-start your own project, and detailed, beginner-friendly tutorials to guide you through the codebase.

The Ask:

Does this sound like a useful idea? Is there a market for something like this? Or am I barking up the wrong tree?

I’ve summarized the pitch in this screenshot of the landing page. (Note: still a work in progress!)

https://manuel.kiessling.net/images/Starter-Kit-for-Symfony/2024-12-23-Starter-Kit-for-Symfony-Landinpage-Screenshot.png

Looking forward to hearing your thoughts — please don’t hold back!

22
 
 
The original post: /r/php by /u/ln3ar on 2024-12-23 10:44:02.
23
 
 
The original post: /r/php by /u/brendt_gd on 2024-12-23 07:00:09.

Hey there!

This subreddit isn't meant for help threads, though there's one exception to the rule: in this thread you can ask anything you want PHP related, someone will probably be able to help you out!

24
 
 
The original post: /r/php by /u/VonFacington on 2024-12-22 17:46:23.

I have an app with Nginx directly serving static content and proxying PHP requests through to FrankenPHP. I recently realized that I was applying encode zstd br gzip at the FrankenPHP (Caddyfile) level and gzip level 6 at the Nginx level. That seemed redundant, so I turned off the encoding at the FrankenPHP level, and that reduced the size of the payload transferred to the browser. Curious as to what kind of configurations those of you with a similar setup have done to optimize how Nginx and FrankenPHP work together?

25
 
 
The original post: /r/php by /u/codemunky on 2024-12-22 17:22:39.

I just happened to have a look at the contents of /var/lib/php/session, and among the thousands of

sess_<32 hexadecimal characters>

files, there's two which are

sess_<32 alpha-numeric characters> (i.e. not just 0-9a-f)

Which seems very strange. Has anyone else ever noticed this or have any explanation for it?

view more: next ›