1. Go to this page and download the library: Download neophp-dev/neophp library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
neophp-dev / neophp example snippets
declare(strict_types=1);
namespace Neo\Src\Blog\App\Services;
use Neo\Core\Utils\Cache\CacheManager;
use Neo\Core\Utils\Logger\LoggerManager;
final class ReportService
{
public function __construct(
private CacheManager $cache,
private LoggerManager $logger
) {
}
public function build(): array
{
$this->logger->info('Generating the report');
return $this->cache->get('report.latest', []);
}
}
declare(strict_types=1);
final class MigrationVersion_20260606120000
{
public function up(DatabaseManager $db): void
{
$db->execute('CREATE TABLE posts (id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY)');
}
public function down(DatabaseManager $db): void
{
$db->execute('DROP TABLE posts');
}
}
#[Route(path: '/', name: 'store', methods: ['POST'])]
public function store(): Response
{
$post = new Post();
$post->setTitle((string) $this->request->body('title'));
$this->entityManager->persist($post);
$this->entityManager->flush();
return $this->jsonSuccess(['id' => $post->getId()], 201);
}
declare(strict_types=1);
namespace Neo\Src\Blog\Database\Repository;
use Neo\Core\Database\ORM\Persistence\EntityRepository;
use Neo\Src\Blog\Database\Entity\Post;
/**
* @extends EntityRepository<Post>
*/
final class PostRepository extends EntityRepository
{
}
public function __construct(private PostRepository $posts) {}
public function index(): Response
{
return $this->render('pages/posts/index.html.twig', [
'posts' => $this->posts->findAll(),
]);
}
public function show(int $id): Response
{
$post = $this->posts->find($id);
return $this->render('pages/posts/show.html.twig', ['post' => $post]);
}
declare(strict_types=1);
namespace Neo\Src\Blog\Database\Entity;
use Neo\Core\Database\ORM\Collection\Collection;
use Neo\Core\Database\ORM\Mapping\Attribute\Column;
use Neo\Core\Database\ORM\Mapping\Attribute\Entity;
use Neo\Core\Database\ORM\Mapping\Attribute\GeneratedValue;
use Neo\Core\Database\ORM\Mapping\Attribute\Id;
use Neo\Core\Database\ORM\Mapping\Attribute\JoinColumn;
use Neo\Core\Database\ORM\Mapping\Attribute\ManyToOne;
use Neo\Core\Database\ORM\Mapping\Attribute\OneToMany;
use Neo\Core\Database\ORM\Mapping\Attribute\Table;
use Neo\Src\Blog\Database\Repository\PostRepository;
#[Entity(repositoryClass: PostRepository::class)]
#[Table(name: 'posts')]
final class Post
{
#[Id]
#[GeneratedValue]
#[Column(type: 'integer', unsigned: true)]
private ?int $id = null;
#[Column(type: 'string', length: 255)]
private string $title;
#[ManyToOne(targetEntity: User::class, inversedBy: 'posts')]
#[JoinColumn(name: 'user_id', nullable: false)]
private User $author;
/** @var Collection<Comment> */
#[OneToMany(targetEntity: Comment::class, mappedBy: 'post')]
private Collection $comments;
public function __construct()
{
$this->comments = new Collection();
}
public function getId(): ?int { return $this->id; }
public function getTitle(): string { return $this->title; }
public function setTitle(string $title): static { $this->title = $title; return $this; }
public function getAuthor(): User { return $this->author; }
public function setAuthor(User $author): static { $this->author = $author; return $this; }
/** @return Collection<Comment> */
public function getComments(): Collection { return $this->comments; }
}
declare(strict_types=1);
namespace Neo\Src\Blog\Database\Entity;
use Neo\Core\Database\ORM\Mapping\Attribute\Column;
use Neo\Core\Database\ORM\Mapping\Attribute\Entity;
use Neo\Core\Database\ORM\Mapping\Attribute\GeneratedValue;
use Neo\Core\Database\ORM\Mapping\Attribute\Id;
use Neo\Core\Database\ORM\Mapping\Attribute\Table;
use Neo\Src\Blog\Database\Repository\PostRepository;
#[Entity(repositoryClass: PostRepository::class)]
#[Table(name: 'posts')]
final class Post
{
#[Id]
#[GeneratedValue]
#[Column(type: 'integer', unsigned: true)]
private ?int $id = null;
#[Column(type: 'string', length: 255)]
private string $title;
public function getId(): ?int
{
return $this->id;
}
public function getTitle(): string
{
return $this->title;
}
public function setTitle(string $title): static
{
$this->title = $title;
return $this;
}
}
declare(strict_types=1);
namespace Neo\Src\Blog\Database\Repository;
use Neo\Core\Database\ORM\Persistence\EntityRepository;
use Neo\Src\Blog\Database\Entity\Post;
/**
* @extends EntityRepository<Post>
*/
final class PostRepository extends EntityRepository
{
}
declare(strict_types=1);
namespace Neo\Src\Blog\App\Services;
use Neo\Core\Database\Form\Form;
use Neo\Core\Database\Form\FormFactory;
use Neo\Src\Blog\Database\Entity\User;
final class UserFormService
{
public function __construct(private FormFactory $factory) {}
public function build(?User $user = null): Form
{
$user ??= new User();
return $this->factory->createFor($user)
->add('firstname', 'text', ['label' => 'First name', '
declare(strict_types=1);
namespace Neo\Src\Blog\App\Dto;
use Neo\Core\Validator\Assert\Email;
use Neo\Core\Validator\Assert\EqualToField;
use Neo\Core\Validator\Assert\Length;
use Neo\Core\Validator\Assert\NotBlank;
final class RegisterDto
{
#[NotBlank(message: 'First name is ld: 'password', message: 'Passwords must match.')]
public string $password_confirm = '';
}
declare(strict_types=1);
namespace Neo\Src\Blog\Database\Seeder;
use Neo\Core\Database\ORM\Persistence\EntityManager;
use Neo\Core\Database\Seeder\Attribute\Seeder;
use Neo\Core\Database\Seeder\Interface\SeedInterface;
use Neo\Src\Blog\Database\Entity\Country;
#[Seeder(order: 10, group: 'reference')]
final class CountrySeeder implements SeedInterface
{
public function run(EntityManager $entityManager): void
{
$country = new Country();
$country->setCode('FR')->setName('France');
$entityManager->persist($country);
$entityManager->flush();
}
}
declare(strict_types=1);
namespace Neo\Src\Blog\App\Middlewares;
use Neo\Core\DI\Container;
use Neo\Core\Security\Auth\AuthManager;
use Neo\Core\Security\Middleware\Interface\MiddlewareInterface;
final class AdminAccessMiddleware implements MiddlewareInterface
{
private AuthManager $auth;
public function __construct(Container $container)
{
$this->auth = $container->get(AuthManager::class);
}
public function handle(): bool
{
return $this->auth->check() && $this->auth->hasRole('admin');
}
}
#[MainRoute(path: '/admin', name: 'admin')]
#[Middleware(use: AuthMiddleware::class, redirect: 'login.index')]
#[Middleware(use: RoleMiddleware::class, params: ['role' => 'admin'])]
final class DashboardController extends AbstractController
{
#[Route(path: '/', name: 'index', methods: ['GET'])]
#[RateLimit(maxAttempts: 20, decaySeconds: 60)]
public function index(): Response
{
return $this->render('pages/admin/index.html.twig');
}
}
#[MainRoute(path: '/admin', name: 'admin')]
#[IsGranted(roles: ['admin'])]
final class DashboardController extends AbstractController
{
#[Route(path: '/users', name: 'users', methods: ['GET'])]
#[IsGranted(roles: ['admin', 'superadmin'])]
public function users(): Response
{
return $this->render('pages/admin/users.html.twig');
}
}
declare(strict_types=1);
namespace Neo\Src\Blog\App\Event;
use Neo\Core\Event\Abstract\AbstractEvent;
final class UserRegisteredEvent extends AbstractEvent
{
public function __construct(public readonly int $userId)
{
}
}
declare(strict_types=1);
namespace Neo\Src\Blog\App\Event\Listener;
use Neo\Core\Event\Attribute\AsListener;
use Neo\Src\Blog\App\Event\UserRegisteredEvent;
#[AsListener(event: UserRegisteredEvent::class, priority: 0)]
final class SendWelcomeEmailListener
{
public function handle(UserRegisteredEvent $event): void
{
$userId = $event->userId;
}
}
$manager = $container->get(MarkdownManager::class);
// From a file
$blocks = $manager->blocks('docs/guide.md');
// From a string
$blocks = $manager->parse("## Title\n\nContent.");