Nantes Born in
Ivry-sur-Seine, France, Hanni started out his career at
Ivry, where his father was coaching when he first joined, and
Boulogne-Billancourt before joining
FC Nantes in 2005. In the last game of the 2008–09 season against
Auxerre, Hanni was called up to the first team for the first team by Manager
Élie Baup, appearing as an unused substitute. Hanni made his professional debut on 1 December 2009 in a league match against
Sedan, making his only appearance in the 2009–10 season. On 11 June 2010, Hanni was slated to sign a one-year contract with hometown club
Paris Saint-Germain. However, a week later, it was announced that he would not be joining the club due to a disagreement between the club and the player's father. It wasn't until on 12 February 2011 when he made his first appearance of the 2010–11 season, coming on as a late substitute, in a 1–0 loss against
Vannes OC. Hanni made his first starts for FC Nantes, playing 71 minutes before being substituted, in a 0–0 draw against
Châteauroux. At the end of the 2010–11 season, Hanni went on to make three appearances for the side. Following this, Hanni was not offered a new contract by FC Nantes, which disappointed him, as he was expected to succeed at the club and experienced this as a failure.
Kayseri Erciyesspor After leaving FC Nantes, Hanni revealed that his agent offered him a move to Turkey, but he wasn't interested. Hanni made his Kayseri Erciyesspor debut, starting the whole game, in a 1–1 draw against
Bucaspor on 10 September 2011 in the opening game of the season. It wasn't until on 25 September 2011 when he scored his first goal for Kayseri Erciyesspor, in a 2–1 win against
Kartalspor. Seven days later on 2 October 2011, Hanni scored his second goal for the club, in a 1–0 win against
Karşıyaka. In a follow–up match against
Çaykur Rizespor on 15 October 2011, he set up two goals for
Gökhan Kaba, who scored twice, in a 4–0 win. He later added two more goals for the side later in the year. Hanni then went three months without scoring; this lasted until 4 March 2012 when he scored in a 2–0 win against
İstanbul Güngörenspor. He then went on a goal scoring spree between 1 April 2012 and 14 April 2012, including scoring twice against
Göztepe. Hanni scored his tenth goal of the season, as well as, setting up the club's second goal of the game, in a 2–0 win against
Sakaryaspor on 5 May 2012. Having established himself in the first team regular for the side, playing in the attacking midfield position, Hanni finished his first season at Kayseri Erciyesspor, making thirty–two appearances and scoring ten times in all competitions. In the 2012–13 season, Hanni continued to retain his place in the first team, playing in the attacking midfield position. Hanni scored his first goals for the club, in a 2–0 against Göztepe on 14 October 2012. Throughout the 2012–13 season, he began to play a role for the side when he assisted goals that saw him assisted sixteen times. Hanni set up five goals in three matches between 11 November 2012 and 24 November 2012, including twice against
Kartalspor. He also set up two goals in two separate matches earlier in the season. It wasn't until in the last game of the season against
Şanlıurfaspor when he scored twice once again, in a 3–1 win. As a result, Kayseri Erciyesspor were TFF First League champions after finishing first place in
the league, resulting in their promotion to
Süper Lig. At the end of the 2012–13 season, Hanni went on to make thirty–four appearances and scoring four times in all competitions.
Ankaraspor Over the summer transfer window, Hanni was linked a move away from Kayseri Erciyesspor, with several Turkish clubs, including
Balıkesirspor, interested in signing him. It was announced on 7 September 2013 that Hanni joined the second Turkish division side,
Ankaraspor A.Ş., signing a four–year contract. In a follow–up match against
Fethiyespor, he scored his first goal for the club, in a 2–1 win. It wasn't until on 2 December 2013 when Hanni scored a brace, as well as, setting the other two goals, in a 4–0 win against
Şanlıurfaspor. A month later, he scored his fourth goal, in a 1–0 win against
Manisaspor, followed up by scoring again, as well as, setting up the club's first goal of the game, in a 2–0 win against
Kahramanmaraşspor. Hanni then set up two goals in three separate matches, starting against
Adana Demirspor on 19 February 2014, then against
Gaziantep on 2 March 2014 and against
Mersin İdman Yurdu on 20 April 2014. He also scored two more goals later in the 2013–14 season. At the end of the 2013–14 season, Hanni finished his first season at Ankaraspor, making thirty–four appearances and scoring eight times in all competitions.
KV Mechelen After three years in Turkey, Hanni moved to Belgium, where he joined
KV Mechelen on a free transfer, signing a three–year contract in May 2014. He cited a move to Belgium over family reasons and staying closer to Paris. Since joining the club, he quickly became a first team regular for the side, playing in the attacking midfield position and spoke out about his development, stating his statistics needs improving. It wasn't until on 13 September 2014 when Hanni scored the club's third goal of the game against
Westerlo, as well as, setting up the club's fifth goal for
Mats Rits, who scored twice during the game, in a 5–2 win. Hanni started in every match since the start of the season until he was dropped to the substitute bench unused, in a 2–2 draw against
Charleroi on 7 February 2015. But Hanni was able to return to the starting line-up against Anderlecht on 15 February 2015 and made an impressive display before being substituted in the late minutes, in a 1–1 draw. He spent three months without scoring a goal and this ended, scoring in the two matches between 22 February 2015 and 28 February 2015 against
Lierse and
Zulte Waregem. In the
league's Group Stage playoffs for the UEFA Europa League spot, Hanni played an important role to help the side finish at the top by scoring four goals, including a brace against Zulte Waregem on 2 May 2015. Hanni then played in
both legs of the league's playoffs for the UEFA Europa League spot against
Lokeren; scoring in the second leg, in a 2–1 win, as KV Mechelen went on to win 4–3 on aggregate. However against Charleroi in
the league's Testmatches for the UEFA Europa League spot, Hanni played in both legs, as he failed to overcome the deficit following KV Mechelen's 3–2 loss on aggregate. In his first season at KV Mechelen, he went on to make forty–three appearances and scoring ten times in all competitions. Ahead of the 2015–16 season, Hanni was linked a move away from KV Mechelen, with
Bundesliga side
Werder Bremen was interested in signing him, but nothing came of it. At the start of the 2015–16 season, he continued to regain his first team place in his second season at the club and became the offensive leader of the club and form a good duo with
Tim Matthys, but started off with a discreet beginning of season, not finding the net. It wasn't until on 17 October 2015 when Hanni scored his first goal of the season against
Sint-Truidense, in the 11th round of
Jupiler League, as well as, being involved in the other two goals, which were scored by
Milos Kosanovic and
Tim Matthys, in a 3–0 win; after the match, he was named the best player of the day by the press. In a follow up match against Zulte Waregem in the 12th round of Jupiler League, he scored twice, including scoring the club's second goal of the game from a direct free kick, as KV Mechelen lost 4–3 in a dramatic confrontation. Then a week later on 31 October 2015, Hanni scored his fourth goal of the season against
Waasland-Beveren on behalf of 14th round of Jupiler League, as well as, setting up the club's second goal of the game, in a 2–0 win, which moved the club to the 11th place in the standings with 15 points. His fifth goal of the season came on 22 November 2015 against
Oostende in the 16th round of Jupiler League, scoring the opening goal of the game, as KV Mechelen won 2–1. On 5 December 2015 against
Royal Excel Mouscron, he contributes again, scoring from a header in a 3–2 win. A week later on 12 December 2015 against Lokeren, Hanni scored again, scoring in mark at the 8th minute with a superb strike from 30 meters, as the match ended in a 1–1 draw. He then scored in the next three matches. His performance at KV Mechelen attracted interests from clubs in Russia and China, but Hanni remained at the club for the rest of the 2015–16 season. Shortly after, Hanni scored the next two goals in two matches on 14 February 2016 and 21 February 2016, scoring against Sint-Truidense and Zulte Waregem. In the 30th round of the Jupiler League, he scored and set up two goals for
Nicolas Verdier, in a 4–0 against
Standard Liège. In the
league's Group Stage playoffs for the UEFA Europa League spot, Hanni scored three goals during the stage, including a brace against Charleroi on 16 April 2016, resulting in a 3–2 loss. Following its full and regular season, in what proved to be his breakthrough season, he ended the season, making thirty–eight appearances, scoring seventeen goals and providing seven assists in all competitions. Following this, Hanni won the Belgian Lion (Best Arab Player of Belgian football championship) on 2 May 2016 and seven days later on 9 May 2016, he succeeded
Neeskens Kebano, winning the
Ebony Boot in 2016 which rewards the best African player of African origin or the Belgian championship. It is the first Algerian football player to win this trophy. Hanni reflected the 2015–16 season, calling it "his best season at the professional level". In addition, he was named
Belgian Footballer of the Year 2015–16, attracting the attention of
Ànderlecht.
Anderlecht in the UEFA Champions League Qualifier Round. On 20 May 2016,
Anderlecht announced the signing of Hanni from
Mechelen for a fee of
€3 million on a four-year contract, which newspaper
Het Nieuwsblad describe the move as "the most lucrative transfer ever for KV Mechelen." Hanni played his first official game with his new club in the
preliminary round of the UEFA Champions League against the Russian club
Rostov scored his first goal with the team and after that missing a significant opportunity by not fit, delivers an assist to
Tielemans which doubles the score in the first Continental participation in its history. However, in the second leg on 3 August 2016, the club lost 2–0, therefore being eliminated in the UEFA Champions League. Hanni made his Anderlecht debut in the opening game of the season against
Royal Excel Mouscron, where he started the whole game and set up a goal for
Idrissa Sylla, who scored a winning goal, in a 2–1 win. In a follow up match against
K.V. Kortrijk, Hanni scored his first league goal for the club, as well as, setting up the club's second goal of the game, in a 5–1 win. Five days later on 12 August 2016, he captained the side for the first time in the absence of
Steven Defour, where he started the match before being substituted in the 81st minute, in a 0–0 draw against Sint-Truidense. Hanni played and captained in both legs of the UEFA Europa League Qualifying against
Slavia Prague, scoring in the first leg, as Anderlecht won 6–0 on aggregate. He scored again on 11 September 2016, in a 3–2 win against Charleroi, and scored two weeks later on 25 September 2016, in a 2–1 loss against
Westerlo. Having quickly become a first team regular since joining Anderlecht, Hanni spent the next four months as the club's captain, helping the side reach the top of the table. He spoke about his development as the club's captain in Defour's absent. During a 1–1 draw against
Saint-Étienne on 29 September, he suffered a pain in the adductor muscles in the last fifteen minutes and had to be substituted. But he recovered quickly and started in a match against rivals, Standard Liège, on 2 October 2016 before being substituted in the 75th minute, as Anderlecht won 1–0, earning their first win against their rival since 2012. Following a 3–2 loss against Zulte Waregem on 27 November 2016, Hanni made a comment about Manager
René Weiler, leading to the Belgium media claims that the pair had fallen out and igniting transfer report claims. But Hanni responded that denied claims from the Belgian media that the pair fell out. He then played an important role as captain when he provided three assists in the UEFA Europa League Group Stage that saw them qualified for the knockout stage. Hanni ended his two months goal drought when he scored the club's second goal of the game, in a 7–0 win against Royal Excel Mouscron on 27 November 2016. This was followed up by setting up the club's last two goals, in a 3–1 win against K.V. Kortrijk. Two weeks later on 18 December 2016, Hanni scored twice, scoring the club's first and fourth goal of the game, in a 4–0 win against
Eupen. He missed two matches at the beginning of January, due to his international commitment with Algeria at the African Cup of Nations campaign. It wasn't until on 29 January 2017 when Hanni made his first team return from his international commitment, coming on as a 75th-minute substitute, in a 0–0 draw against rivals, Standard Liège. He then scored two goals in two matches between 12 February 2017 and 19 February 2017 against Zulte Waregem and
Oostende. Two months later on 16 April 2017, Hanni scored against Oostende once again, scoring the only goal of the game, in a 1–0 win. Four days later on 20 April 2017 in the second leg of the quarter–finals of the UEFA Europa League against
Manchester United, he scored an equaliser, as they lost 2–1 and the club was eliminated from the tournament. Hanni then scored his thirteenth goal of the season, in a 1–1 draw against
Club Brugge, as the club becomes closer to win the title. In a follow up match against Charleroi, he set up the club's last two goals of the game, in a 3–1 win, a result that saw Anderlecht becomes the Jupiler League's champion. Despite missing one match due to a groin injury during the 2016–17 season, Hanni was nominated for Belgian Lion Award and Belgian Professional Footballer of the Year but lost out to
Ishak Belfodil and
Youri Tielemans respectively. But his goal against Oostende, nevertheless, earned him the Goal of the Year award. Ahead of the 2017–18 season, Hanni signed a contract extension with the club, keeping him until 2022. At the start of the 2017–18 season, he continued to resume his duties as the club's captain, as well as, his first team place. Hanni captained the side in the
Belgium Super Cup match against Zulte Waregem and scored an equalising goal, as they won 2–1. Two weeks later on 6 August 2017, he scored his first league goal of the season, in a 1–0 win against Oostende. Three months later on 13 October 2017 against KV Mechelen, Hanni set up two goals, setting up the club's first two goals of the game, in a 4–2 win. Later in October, he scored the club's third goal of the game, in a 3–2 win against Eupen. Hanni made his UEFA Champions League debut, playing the whole game, in a 2–1 loss against
Bayern Munich on 12 September 2017. Two months later on 22 November 2017, Hanni scored his first UEFA Champions League goal against Bayern Munich in their second meeting, as Anderlecht lost 3–1. Four days later on 26 November 2017, he scored the club's second goal of the game, in a 4–0 win against
K.V. Kortrijk. Hanni later scored four more goals for the side, including a hat–trick, in a 3–3 draw against Standard Liège on 28 January 2018, in what turned out to be his last appearance for Anderlecht. In the January transfer window, he was linked with a move away from Anderlecht, with several Russian clubs interested in signing him. By the time he departed Anderlecht, Hanni went on to make thirty–one appearances and scoring ten times in all competitions. His relationship with Anderlecht supporters has been strained as the reason of his departure.
Spartak Moscow on 11 March 2018. On 31 January 2018, Hanni signed a three-and-a-half-year contract with Russian defending champions
Spartak Moscow. Upon joining the club, he stated the move to Spartak Moscow was a decision he couldn't refuse and he was motivated to win trophies at his new club. on 29 September 2018. Hanni made his Spartak Moscow debut, facing in the first leg of the UEFA Europa League's Round of 32 against
Athletic Bilbao, coming on as a 75th-minute substitute, in a 2–1 loss. However, the club were eliminated from the tournament despite winning 2–1 in the second leg but lost 4–3 on aggregate. He made his league debut for the club, coming on as a 58th-minute substitute, in a 2–1 win against
SKA-Khabarovsk on 11 March 2018. In a follow–up match against
Rubin Kazan, Hanni scored his first FC Spartak Moscow goal, in a 2–1 win. He later scored his second goal for FC Spartak Moscow, in a 2–0 win against
Amkar Perm on 29 April 2018. For the rest of the 2017–18 season, Hanni spent coming on as a substitute for the remaining matches, as he made nine appearances and scoring two times in all competitions. on 8 November 2018. However at start of the 2018–19 season, Hanni found himself placed on the substitute bench, due to a strong competitions within the midfield positions. This led to speculation over his future at Spartak Moscow. Amid the transfer speculation, Hanni made his first appearance of the season, starting a match before being substituted in the 65th minute, in a 1–0 win against
Anzhi Makhachkala. By September, he soon received more playing time following the departure of
Quincy Promes and started in a number of matches in the midfield position. Hanni played a role when he set up two goals between 26 September 2018 and 4 October 2018 against
Chernomorets Novorossiysk and
Villarreal. He then scored three goals in three separate competitions, scoring against
Rangers, Anzhi Makhachkala and
Krylia Sovetov Samara. For his performance, Hanni was named the league's best player of the month. He continued to play a role when he set up two goals, in a 2–1 win against
Lokomotiv Moscow, followed up by scoring in a 1–1 draw against
Ural Yekaterinburg in the first leg of the Russian Cup quarter–final. His performance against Lokomotiv Moscow earned him a spot for the league's Team of the Week. Towards the end of the 2018–19 season, Hanni continued to feature in the first team despite being on the sidelines on two occasions. At the end of the 2018–19 season, he went on to make twenty–seven appearances and scoring four times in all competitions. Ahead of the 2019–20 season, Hanni's future at Spartak Moscow became a subject from the Russian media once again. He responded to the claims, stating his desire to stay at the club on two separate statements. Hanni appeared as an unused substitute in the opening game of the season against
PFC Sochi.
Al-Gharafa On 22 July 2019,
Al-Gharafa has signed Hanni for one season from
Spartak Moscow. The move reported to have cost 6 million euros. The club's sporting director Tomas Zorn said Hanni left the club because he wanted to pursue first team football. Hanni quickly made an impact on his Al-Gharafa's debut, scoring and setting up two goals, in a 3–0 win against
Al-Shahania in the opening game of the season. Between 20 October 2019 and 23 January 2020, he went on a goal scoring spree, scoring nine times in seven matches, including a brace against
Al-Khor. He went on a three matches without scoring a goal and this ended on 4 March 2020, scoring in a 2–1 win against
Al-Wakrah. ==International career==