PHPackages                             onspli/chess - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. onspli/chess

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

onspli/chess
============

PHP library for reading and editing FEN and PGN chess formats.

v0.2.0(4y ago)41.7k↑31.1%1MITPHPPHP ^7.2|^8.0

Since Sep 18Pushed 4y ago1 watchersCompare

[ Source](https://github.com/onspli/chess)[ Packagist](https://packagist.org/packages/onspli/chess)[ RSS](/packages/onspli-chess/feed)WikiDiscussions master Synced 2w ago

READMEChangelog (2)Dependencies (4)Versions (3)Used By (0)

onspli/chess
============

[](#onsplichess)

PHP library for reading and editing FEN and PGN chess formats.

[![build](https://github.com/onspli/chess/actions/workflows/build.yml/badge.svg)](https://github.com/onspli/chess/actions/workflows/build.yml/badge.svg) [![license](https://camo.githubusercontent.com/f00d1046ce10f8e8f563e85ff31859c4aad8f7d7369f0334e8af4348e27275ef/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f6f6e73706c692f63686573733f6c6162656c3d6c6963656e7365)](https://github.com/onspli/chess/blob/master/LICENSE) [![coverage](https://camo.githubusercontent.com/9dea4f8200830bc5018f048c64998fafd2544171524c8b3e0fcdc0d4e8534653/68747470733a2f2f636f766572616c6c732e696f2f7265706f732f6769746875622f6f6e73706c692f63686573732f62616467652e7376673f6272616e63683d6d6173746572)](https://coveralls.io/github/onspli/chess?branch=master) [![maintainability](https://camo.githubusercontent.com/acf8762bf8c5d96b203d58e242b9a5f4edec5ec42a76471c289498ea90f761cf/68747470733a2f2f6170692e636f6465636c696d6174652e636f6d2f76312f6261646765732f34633266376161663536336131663439326332312f6d61696e7461696e6162696c697479)](https://codeclimate.com/github/onspli/chess/maintainability) [![last commit](https://camo.githubusercontent.com/53c31c78654b20a0c375d7c66d2994b0c6ccc34dba4a3f39657f40db5ada074d/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6173742d636f6d6d69742f6f6e73706c692f6368657373)](https://github.com/onspli/chess)

Features
--------

[](#features)

### FEN class

[](#fen-class)

- load FEN representing chess position (standard or Shredder-FEN)
- read and modify all FEN fields
- export FEN
- read and set piece placement
- get or set piece on any square
- test position for check, mate, stalemate
- test position for fifty-move rule
- perform move in given position
- test if move is legal in given position
- list all legal moves in given position
- supports Fisher's random (Chess960)

### PGN class

[](#pgn-class)

- load PGN representing chess game
- read and set all tag pairs (PGN headers)
- export PGN
- read and add moves
- get FEN position after any move
- supports Fisher's random (Chess960)

Installation
------------

[](#installation)

Install with composer:

```
composer require onspli/chess

```

Usage
-----

[](#usage)

Read complete auto-generated [documentation](docs) or learn from the following examples.

Setup chess board to starting position and read FEN fields.

```
$fen = new Onspli\Chess\FEN;
echo($fen->export());
// rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1
echo($fen->export_short());
// rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
echo($fen->get_board());
// rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR
echo($fen->get_active_color());
// w
echo($fen->get_castling());
// KQkq
echo($fen->get_en_passant());
// -
echo($fen->get_halfmove());
// 0
echo($fen->get_fullmove());
// 1
echo($fen->preview());
/*
rnbqkbnr
pppppppp
........
........
........
........
PPPPPPPP
RNBQKBNR
*/
```

Initialize custom position and read FEN fields.

```
$fen = new Onspli\Chess\FEN('rnbqkbnr/pp1ppppp/8/2p5/4P3/8/PPPP1PPP/RNBQKBNR b KQq c6 1 2');
echo($fen->export());
// rnbqkbnr/pp1ppppp/8/2p5/4P3/8/PPPP1PPP/RNBQKBNR b KQq c6 1 2
echo($fen->export_short());
// rnbqkbnr/pp1ppppp/8/2p5/4P3/8/PPPP1PPP/RNBQKBNR b KQq c6
echo($fen->get_board());
// rnbqkbnr/pp1ppppp/8/2p5/4P3/8/PPPP1PPP/RNBQKBNR
echo($fen->get_active_color());
// b
echo($fen->get_castling());
// KQq
echo($fen->get_en_passant());
// c6
echo($fen->get_halfmove());
// 1
echo($fen->get_fullmove());
// 2
echo($fen->preview());
/*
rnbqkbnr
pp.ppppp
........
..p.....
....P...
........
PPPP.PPP
RNBQKBNR
*/
```

Manipulate with pieces.

```
$fen = new Onspli\Chess\FEN;
echo($fen->get_square('a1'));
// R
$fen->set_square('a1', '');
$fen->set_square('a3', 'R');
echo($fen->preview());
/*
rnbqkbnr
pppppppp
........
........
........
R.......
PPPPPPPP
.NBQKBNR
*/
```

Each of the fields can be set with the corresponding setter:

```
$fen = new Onspli\Chess\FEN;
echo($fen->export());
// rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1
$fen->set_board('rnbqkbnr/pp1ppppp/8/2p5/4P3/8/PPPP1PPP/RNBQKBNR');
$fen->set_active_color('b');
$fen->set_castling('KQq');
$fen->set_en_passant('c6');
$fen->set_halfmove(1);
$fen->set_fullmove(2);
echo($fen->export());
// rnbqkbnr/pp1ppppp/8/2p5/4P3/8/PPPP1PPP/RNBQKBNR b KQq c6 1 2
echo($fen->preview());
/*
rnbqkbnr
pp.ppppp
........
..p.....
....P...
........
PPPP.PPP
RNBQKBNR
*/
```

Perform moves:

```
$fen = new Onspli\Chess\FEN;
echo($fen->preview());
/*
rnbqkbnr
pppppppp
........
........
........
........
PPPPPPPP
RNBQKBNR
*/
$fen->move('e4');
$fen->move('g6');
$fen->move('Nf3');
$fen->move('Nf6');
$fen->move('Bc4');
$fen->move('Bg7');
$fen->move('O-O');
$fen->move('O-O');
echo($fen->preview());
/*
rnbq.rk.
ppppppbp
.....np.
........
..B.P...
.....N..
PPPP.PPP
RNBQ.RK.
*/
echo($fen->export());
// rnbq1rk1/ppppppbp/5np1/8/2B1P3/5N2/PPPP1PPP/RNBQ1RK1 w - - 6 5
```

Test check, mate, stalemate:

```
$fen = new Onspli\Chess\FEN;
$fen->set_active_color('w');
$fen->set_board('1q5k/8/8/8/8/8/8/K7');
$fen->set_castling('-');
echo($fen->is_check() ? 'true' : 'false');
// false
echo($fen->is_stalemate() ? 'true' : 'false');
// false
echo($fen->preview());
/*
.q.....k
........
........
........
........
........
........
K.......
*/
$fen->move('Ka2');
$fen->move('Qa8');
echo($fen->is_check() ? 'true' : 'false');
// true
echo($fen->is_mate() ? 'true' : 'false');
// false
echo($fen->preview());
/*
q......k
........
........
........
........
........
K.......
........
*/
```

List all possible moves:

```
$fen = new Onspli\Chess\FEN;
$fen->move('e4');
$fen->move('g6');
echo($fen->preview());
/*
rnbqkbnr
pppppp.p
......p.
........
....P...
........
PPPP.PPP
RNBQKBNR
*/
print_r($fen->get_legal_moves());
/*
Array
(
    [0] => a4
    [1] => a3
    [2] => b4
    [3] => b3
    [4] => c4
    [5] => c3
    [6] => d4
    [7] => d3
    [8] => f4
    [9] => f3
    [10] => g4
    [11] => g3
    [12] => h4
    [13] => h3
    [14] => e5
    [15] => Nc3
    [16] => Na3
    [17] => Ne2
    [18] => Nh3
    [19] => Nf3
    [20] => Be2
    [21] => Bd3
    [22] => Bc4
    [23] => Bb5
    [24] => Ba6
    [25] => Qe2
    [26] => Qf3
    [27] => Qg4
    [28] => Qh5
    [29] => Ke2
)

*/
```

Load game in PGN notation and read tags and moves:

```
$pgn = new Onspli\Chess\PGN('[Event "Testing"] 1.Nf3 Nf6 2.c4 g6');
echo($pgn->get_tag('Event'));
// Testing
echo($pgn->get_halfmove(2));
// Nf6
echo($pgn->get_initial_halfmove_number());
// 1
echo($pgn->get_last_halfmove_number());
// 4
```

Record new moves, add tags and export PGN:

```
$pgn = new Onspli\Chess\PGN('[Event "Testing"] 1.Nf3 Nf6 2.c4 g6');
$pgn->set_tag('Site', 'Github');
$pgn->move('a4');
$pgn->move('a5');
print_r($pgn->get_tags());
/*
Array
(
    [Event] => Testing
    [Site] => Github
)

*/
echo($pgn->export_tags());
/*
[Event "Testing"]
[Site "Github"]

*/
echo($pgn->export_movetext());
// 1. Nf3 Nf6 2. c4 g6 3. a4 a5
echo($pgn->export());
/*
[Event "Testing"]
[Site "Github"]
1. Nf3 Nf6 2. c4 g6 3. a4 a5
*/
```

Extract position after certain move:

```
$pgn = new Onspli\Chess\PGN('1.Nf3 Nf6 2.c4 g6');
echo($pgn->get_current_fen());
// rnbqkb1r/pppppp1p/5np1/8/2P5/5N2/PP1PPPPP/RNBQKB1R w KQkq - 0 3
echo($pgn->get_initial_fen());
// rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1
echo($pgn->get_fen_after_halfmove(0));
// rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1
echo($pgn->get_fen_after_halfmove(2));
// rnbqkb1r/pppppppp/5n2/8/8/5N2/PPPPPPPP/RNBQKB1R w KQkq - 2 2
echo($pgn->get_fen_after_halfmove(Onspli\Chess\PGN::get_halfmove_number(1, 'b')));
// rnbqkb1r/pppppppp/5n2/8/8/5N2/PPPPPPPP/RNBQKB1R w KQkq - 2 2
```

FEN is returned as `string` by default. Passing parameter `$as_object = true` makes it FEN object:

```
$pgn = new Onspli\Chess\PGN('1.Nf3 Nf6 2.c4 g6');
echo($pgn->get_current_fen(true)->preview());
/*
rnbqkb.r
pppppp.p
.....np.
........
..P.....
.....N..
PP.PPPPP
RNBQKB.R
*/
echo($pgn->get_fen_after_halfmove(2, true)->preview());
/*
rnbqkb.r
pppppppp
.....n..
........
........
.....N..
PPPPPPPP
RNBQKB.R
*/
```

PGN with custom initial position:

```
$pgn = new Onspli\Chess\PGN('[FEN "rnbqkb1r/pppp1ppp/5n2/4p3/2P1P3/5N2/PP1P1PPP/RNBQKB1R b KQkq - 0 3"] 3... Nc6 4. Qb3');
echo($pgn->get_initial_fen());
// rnbqkb1r/pppp1ppp/5n2/4p3/2P1P3/5N2/PP1P1PPP/RNBQKB1R b KQkq - 0 3
echo($pgn->get_initial_halfmove_number());
// 6
echo($pgn->get_halfmove(6));
// Nc6
```

###  Health Score

28

—

LowBetter than 51% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity25

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity48

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~251 days

Total

2

Last Release

1544d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/413b99f734b277cbf822e1726f13864540b9ae61e5dfe18154507605dc1af4ab?d=identicon)[onspli](/maintainers/onspli)

---

Top Contributors

[![onspli](https://avatars.githubusercontent.com/u/7120489?v=4)](https://github.com/onspli "onspli (138 commits)")

---

Tags

chessfenpgnphp

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/onspli-chess/health.svg)

```
[![Health](https://phpackages.com/badges/onspli-chess/health.svg)](https://phpackages.com/packages/onspli-chess)
```

###  Alternatives

[pid/speakingurl

Generate of so called 'static' or 'Clean URL' or 'Pretty URL' or 'nice-looking URL' or 'Speaking URL' or 'user-friendly URL' or 'SEO-friendly URL' or 'slug' from a string.

1.1k5.4k1](/packages/pid-speakingurl)[kunstmaan/seo-bundle

Annotating content with metadata for social sharing and seo purposes cannot be overlooked nowadays. The KunstmaanSeoBundle contains default editing functionality for OpenGraph data, meta descriptions, keywords and titles and Metriweb tags. Because the metatagging and tracking options are always changing, a free field to add custom header information is provided as well.

28132.7k2](/packages/kunstmaan-seo-bundle)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
